• ElasticSearch入门 第五篇:使用C#查询文档


    ElasticSearch入门 第五篇:使用C#查询文档

     

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

    使用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

    作者悦光阴
    本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    instanceof方法
    Java 实现接口计算圆柱的体积和面积并添加颜色
    Java代码执行顺序
    Java饿汉单例模式
    斐波那契数(动态规划和递归)
    Java 接口实现计算器加减乘除(字符交互界面)
    局部内部类详解_转载
    Java引用类型
    递归打印字符串
    时间复杂度
  • 原文地址:https://www.cnblogs.com/Jeely/p/11315326.html
Copyright © 2020-2023  润新知