網址:http://www.cnblogs.com/ljhdo/p/4550135.html
這是ElasticSearch 2.4 版本系列的第五篇:
- ElasticSearch入門 第一篇:Windows下安裝ElasticSearch
- ElasticSearch入門 第二篇:集群配置
- ElasticSearch入門 第三篇:索引
- ElasticSearch入門 第四篇:使用C#添加和更新文檔
- ElasticSearch入門 第五篇:使用C#查詢文檔
- ElasticSearch入門 第六篇:復合數據類型——數組,對象和嵌套
- ElasticSearch入門 第七篇:分析器
- ElasticSearch入門 第八篇:存儲
- ElasticSearch入門 第九篇:實現正則表達式查詢的思路
使用C#代碼實現對ElastiSearch的編程查詢,是十分方便的,通常情況下,開發者采用官方提供的NEST客戶端程序,通過封裝的方法向ElasticSearch引擎發送查詢請求,搜索數據,最終獲取返回的查詢結果,實現預定的業務需求。在內部,NEST客戶端通過格式化的數據結構,把C#代碼轉換成HTTP 請求(Request),減輕了用戶直接編寫Qeury DSL的麻煩。當然,用戶也可以直接把Query DSL封裝成HTTP請求,發送到ElasticSearch引擎;對開發者來說,不僅需要熟悉Query DSL的語法,而且需要手動編寫代碼,處理引擎返回的JSON結構化的數據集,采用這種方式的優點是不受限於NEST客戶端程序,能夠最大化使用ElasticSearch查詢的各種參數,書寫自由。
本文簡單介紹使用C#代碼對ElasticSearch進行編程查詢的流程,具體的細節,請參考官方文檔。
一,編程流程
1,創建客戶端
在搜索文檔之前,首先要連接到ElasticSearch引擎,創建客戶端對象
using Nest;
var node = new Uri("http://myserver:9200");
var settings = new ConnectionSettings(node).DefaultIndex("default");
var client = new ElasticClient(settings);
2,創建查詢請求
連接到引擎之后,創建搜索請求(SearchRequest),用於封裝查詢類型和查詢條件
SearchRequest sr = new SearchRequest("meetup", "events");
3,指定查詢類型和查詢條件
為搜索請求指定查詢類型,可以是詞條搜索,或全文搜索
TermQuery tq = new TermQuery(); tq.Field = "eventname"; tq.Value = "azure"; sr.Query = tq;
4,調整查詢結果
為搜索請求設置參數,排序,分頁,和選擇返回的字段等,在選擇查詢結果返回的字段時,推薦在查詢請求(SearchRequest)中使用Source Filter。
在查詢請求中,通過類RequestSearch的數組字段StoredFileds,把已存儲字段添加到該數組中,ElasticSearch引擎只返回特定的字段,而不是文檔的所有字段。在索引映射中,已存儲字段的store屬性為true,StoredFileds數組只能選擇已存儲字段(stored field)。
//windows
sr.From = 0;
sr.Size = 100;
//sort
ISort sort = new SortField { Field = "eventid", Order = SortOrder.Ascending };
sr.Sort = new List<ISort>();
sr.Sort.Add(sort);
//source filter
sr.Source = new SourceFilter()
{
Includes = new string[] { "eventid", "eventname" },
Excludes = new string[] { "roginalid", "description" }
};
5,執行查詢請求
最后,客戶端執行搜索請求,獲取搜索結果,並將查詢結果中的文檔集轉換成列表
var result = client.Search<MeetupEvents>(sr); return result.Documents.ToList<MeetupEvents>();
二,示例代碼,使用Nest客戶端搜索文檔
在該示例代碼中,本文簡單列舉詞條查詢,匹配查詢,布爾查詢和正則表達式查詢的示例代碼。
1,詞條查詢
public List<MeetupEvents>GetResult_TermQuery( )
{
//create term query
TermQuery tq = new TermQuery();
tq.Field = "eventname";
tq.Value = "azure";
//create search request
SearchRequest sr = new SearchRequest("meetup", "events");
sr.Query = tq;
//windows
sr.From = 0;
sr.Size = 100;
//sort
ISort sort = new SortField { Field = "eventid", Order = SortOrder.Ascending };
sr.Sort = new List<ISort>();
sr.Sort.Add(sort);
//source filter
sr.Source = new SourceFilter()
{
Includes = new string[] { "eventid", "eventname" },
Excludes = new string[] { "roginalid", "description" }
};
var result = client.Search<MeetupEvents>(sr);
return result.Documents.ToList<MeetupEvents>();
}
2,匹配查詢
public List<MeetupEvents> GetResult_MatchQuery()
{
SearchRequest sr = new SearchRequest("meetup", "events");
MatchQuery mq = new MatchQuery();
mq.Field = new Field("eventname");
mq.Query = "azure cloud";
mq.MinimumShouldMatch = 2;
mq.Operator = Operator.Or;
sr.Query = mq;
sr.From = 0;
sr.Size = 100;
sr.Sort = new List<ISort>();
sr.Sort.Add(new SortField { Field = "eventid", Order = SortOrder.Ascending });
ISearchResponse<MeetupEvents> result = client.Search<MeetupEvents>(sr);
return result.Documents.ToList<MeetupEvents>();
}
3,正則表達式查詢
public List<MeetupEvents>GetResult_RegexpQuery()
{
SearchRequest sr = new SearchRequest();
RegexpQuery rq = new RegexpQuery();
rq.Field = "description";
rq.Value = "azu.*";
rq.MaximumDeterminizedStates = 20000;
sr.Query = rq;
var result = client.Search<MeetupEvents>(sr);
return result.Documents.ToList<MeetupEvents>();
}
4,布爾查詢
public List<MeetupEvents>GetResult_BoolQuery()
{
SearchRequest sr = new SearchRequest("meetup", "events");
BoolQuery bq = new BoolQuery();
bq.Filter = new QueryContainer[]
{
new MatchQuery()
{
Field="eventname",
Query="azure cloud",
Operator=Operator.Or,
MinimumShouldMatch=1
},
new MatchQuery()
{
Field ="eventname",
Query="aws google",
Operator=Operator.Or,
MinimumShouldMatch=1
}
};
bq.Should = new QueryContainer[]
{
new TermQuery()
{
Field="description",
Value="azure"
},
new TermQuery()
{
Field="description",
Value="cloud"
}
};
bq.MinimumShouldMatch = 1;
sr.Query = bq;
var result = client.Search<MeetupEvents>(sr);
return result.Documents.ToList<MeetupEvents>();
}
三,把Query DSL封裝成HTTP Request
向ElasticSearch引擎發送Http請求,在http請求中指定查詢的類型和查詢條件,引擎在收到請求后執行搜索,查詢結果以HTTP 響應(Response)返回,開發者需要從Response返回的JSON結構字符串中解析搜索結果。
1,封裝類庫
以下HTTP網絡編程代碼,是我們項目組一姐Amy的作品,謝謝Amy的分享,代碼可以進一步封裝,在此文中,僅僅作為演示:
namespace ElasticSearchNet
{
class ESRequest
{
string es_host;
string es_port;
string es_index;
string es_type;
private string url;
public ESRequest(string host,string index,string type,string port="9200")
{
es_host = host;
es_port = port;
es_index = index;
es_type = type;
string requst_cache = "request_cache=true";
url = string.Format("http://{0}:{1}/{2}/{3}/_search?{4}", es_host, es_port, es_index, es_type,requst_cache);
}
public string ExecuteQeury(string json_query)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "aplication/json";
request.Method = "POST";
request.Timeout = 1000 * 60;
using (var sw = new StreamWriter(request.GetRequestStream()))
{
sw.Write(json_query);
sw.Flush();
sw.Close();
}
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}
}
2,執行查詢
查詢的結果是JSON結構的字符串,通常使用JObject和JToken類處理。
ESRequest es = new ElasticSearchNet.ESRequest("cia-sh-svr-sis3", "meetup", "events");
string json_query = @"
{ ""query"":{
""match"":{
""eventname"":""azure""
}
}
}
";
string strJsonResult=es.ExecuteQeury(json_query);
解析JSON的常用類庫是:
參考文檔:
Elasticsearch.Net and NEST: the .NET clients [5.x] » Search
Elasticsearch.Net and NEST: the .NET clients [5.x] » Query DSL

