問題描述
- 使用Elasticsearch .NET client 創(chuàng)建ES的實(shí)例,并導(dǎo)入Shapefile數(shù)據(jù)建全文索引和空間索引啡邑。
- Shapefile為地址點(diǎn)數(shù)據(jù)贱勃,需要對(duì)指定的字段進(jìn)行全文檢索(分詞、拼音),支持范圍搜索
ES服務(wù)端配置
#創(chuàng)建實(shí)例
PUT http://localhost:9200/test_index
{
"index":{
"analysis":{
"analyzer":{
"ik_pinyin_analyzer":{
"type":"custom",
"tokenizer":"ik_smart",
"filter":"pinyin_filter"
}
},
"filter":{
"pinyin_filter":{
"type":"pinyin",
"keep_first_letter": false
}
}
}
}
}
#返回結(jié)果
//////////////////返回結(jié)果////////////////////////
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "test_index"
}
///////////////////返回結(jié)果//////////////////////
#配置Mapping
PUT http://localhost:9200/test_index/_mapping/test_type
{
"properties": {
"testfield":{
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"fields": {
"my_pinyin":{
"type":"text",
"analyzer": "ik_pinyin_analyzer",
"search_analyzer": "ik_pinyin_analyzer"
}
}
}
}
}
#返回結(jié)果
//////////////////返回結(jié)果////////////////////////
{
"acknowledged": true
}
//////////////////返回結(jié)果////////////////////////
#索引文檔
POST http://localhost:9200/test_index/test_type
{
"testfield":"今天天氣不錯(cuò)"
}
#返回結(jié)果
//////////////////返回結(jié)果////////////////////////
{
"_index": "test_index",
"_type": "test_type",
"_id": "tjDRIWcBQbCTUJC9qxCs",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
//////////////////返回結(jié)果////////////////////////
#搜索文檔(中文)
POST http://localhost:9200/test_index/test_type/_search
{
"query":{
"match": {
"testfield": "天氣"
}
}
}
#返回結(jié)果
//////////////////返回結(jié)果////////////////////////
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "test_index",
"_type": "test_type",
"_id": "tzDYIWcBQbCTUJC9HRBn",
"_score": 0.2876821,
"_source": {
"testfield": "今天天氣不錯(cuò)"
}
}
]
}
}
//////////////////返回結(jié)果////////////////////////
#搜索文檔(拼音)
POST http://localhost:9200/test_index/test_type/_search
{
"query":{
"match": {
"testfield.my_pinyin": "tianqi"
}
}
}
#返回結(jié)果
//////////////////返回結(jié)果////////////////////////
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.68324494,
"hits": [
{
"_index": "test_index",
"_type": "test_type",
"_id": "tzDYIWcBQbCTUJC9HRBn",
"_score": 0.68324494,
"_source": {
"testfield": "今天天氣不錯(cuò)"
}
}
]
}
}
//////////////////返回結(jié)果////////////////////////
通過以上測(cè)試贵扰,可以確定ES的服務(wù)端功能可以實(shí)現(xiàn)仇穗,接下來就是使用.NET客戶端進(jìn)行調(diào)用
ES客戶端配置
- vs2015 .net 4.6.1
- nuget 安裝 Es.net client
首先建立連接,本機(jī)測(cè)試是單機(jī)部署戚绕,所以連接比較簡(jiǎn)單
var uris = new[] { new Uri("http://localhost:9200") };
var connectionPool = new SniffingConnectionPool(uris);
var settings = new ConnectionConfiguration(connectionPool);
var lowlevelClient = new ElasticLowLevelClient(settings);
ElasticLowLevelClient
這個(gè)類里面封裝了各種操作纹坐,只需要構(gòu)建請(qǐng)求體PostData
就行。官方給出的方法是利用匿名對(duì)象或者字符串列肢,在構(gòu)造復(fù)雜對(duì)象的時(shí)候單獨(dú)使用可能不夠方便恰画,可以根據(jù)情況自行調(diào)整。例如瓷马,導(dǎo)入的shapefile有多個(gè)字段需要分詞拴还,應(yīng)當(dāng)如何動(dòng)態(tài)生成Mappings,還有在用bulk批量導(dǎo)入的時(shí)候欧聘,文檔應(yīng)該如何轉(zhuǎn)成Postdata的格式片林。
目標(biāo)1 根據(jù)需要分詞的字段和固定的空間位置字段生成請(qǐng)求體
分析如下:層次較多,且有動(dòng)態(tài)生成的內(nèi)容怀骤,使用字符串format的方法比較難控制费封。所以固定屬性名的采用匿名對(duì)象的方式,而屬性名動(dòng)態(tài)生成的部分蒋伦,用Dictionary<string, object>
來解決弓摘。
ps C# 中 string.format()的字符串中如果本來有“{}”,需要寫成“{{}}”
public static object setMapping(List<string> splitFields)
{
#region 配置模板
var pinyin_filter_TEMPLATE = new
{
type = "pinyin",
keep_first_letter = false
};
var ik_pinyin_analyzer_TEMPLATE = new
{
type = "custom",
tokenizer = "ik_smart",
filter = "pinyin_filter"
};
var splitField_TEMPLATE = new
{
type = "text",
analyzer = "ik_max_word",
search_analyzer = "ik_max_word",
fields = new
{
my_pinyin = new
{
type = "text",
analyzer = "ik_pinyin_analyzer",
search_analyzer = "ik_pinyin_analyzer"
}
}
};
var shape_TEMPLATE = new
{
type = "geo_point"
};
var settings = new
{
index = new
{
analysis = new
{
analyzer = new
{
ik_pinyin_analyzer = ik_pinyin_analyzer_TEMPLATE
},
filter = new
{
pinyin_filter = pinyin_filter_TEMPLATE
}
}
}
};
#endregion
var propertiesBody = new Dictionary<string, object>();
// 分詞字段
foreach (string field in splitFields)
{
propertiesBody.Add(field, splitField_TEMPLATE);
}
// 空間位置字段
propertiesBody.Add("shape", shape_TEMPLATE);
var properties = new
{
properties = propertiesBody
};
var indexNameTEMPLATE = new Dictionary<string, object>();
// type "addorpoi" 痕届,可以用變量代替韧献,一般type是自定義的
indexNameTEMPLATE.Add("addorpoi", properties);
var mappings = indexNameTEMPLATE;
var settinMapping = new
{
settings = settings,
mappings = mappings
};
return settinMapping;
}
目標(biāo)2 根據(jù)空間位置和指定間距進(jìn)行地址搜索
分析如下:搜索的請(qǐng)求體固定,只要換參數(shù)即可研叫,也可以使用字符串锤窑,雖然不太簡(jiǎn)潔,但是也是一種思路嚷炉。
原有的查詢字符串
{
"query":{
"bool":{
"must":{
"match_all":{}
},
"filter":{
"geo_distance":{
"distance":"100m",
"shape":"30.6321727220001,120.308015149"
}
}
}
}
}
使用https://www.sojson.com/yasuoyihang.html提供的壓縮轉(zhuǎn)義工具渊啰,獲得一行轉(zhuǎn)義的json字符串,再用文本把{
換成{{
同時(shí)}
換成}}
申屹,然后把參數(shù)扣掉換成format需要的形式绘证。
var searchStr = string.Format(searchTemplate, "30.6321727220001,120.308015149", "100");
vat postbody = PostData.String(searchStr);