ElasticSearch入門 第五篇:使用C#查詢文檔

這是ElasticSearch 2.4 版本系列的第五篇:html

 

使用C#代碼實現對ElastiSearch的編程查詢,是十分方便的,一般狀況下,開發者採用官方提供的NEST客戶端程序,經過封裝的方法向ElasticSearch引擎發送查詢請求,搜索數據,最終獲取返回的查詢結果,實現預約的業務需求。在內部,NEST客戶端經過格式化的數據結構,把C#代碼轉換成HTTP 請求(Request),減輕了用戶直接編寫Qeury DSL的麻煩。固然,用戶也能夠直接把Query DSL封裝成HTTP請求,發送到ElasticSearch引擎;對開發者來講,不只須要熟悉Query DSL的語法,並且須要手動編寫代碼,處理引擎返回的JSON結構化的數據集,採用這種方式的優勢是不受限於NEST客戶端程序,可以最大化使用ElasticSearch查詢的各類參數,書寫自由。node

本文簡單介紹使用C#代碼對ElasticSearch進行編程查詢的流程,具體的細節,請參考官方文檔。正則表達式

一,編程流程編程

1,建立客戶端json

在搜索文檔以前,首先要鏈接到ElasticSearch引擎,建立客戶端對象windows

using Nest;
var node = new Uri("http://myserver:9200");
var settings = new ConnectionSettings(node).DefaultIndex("default");
var client = new ElasticClient(settings);

2,建立查詢請求api

鏈接到引擎以後,建立搜索請求(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();
            }
        }
    }
}
View Code

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

相關文章
相關標籤/搜索