Elasticsearch使用系列-.NET6对接Elasticsearch

Elasticsearch使用系列-ES简介和环境搭建

Elasticsearch使用系列-ES增删查改基本操作+ik分词

Elasticsearch使用系列-基本查询和聚合查询+sql插件

Elasticsearch使用系列-.NET6对接Elasticsearch

Elasticsearch使用系列-Docker搭建Elasticsearch集群

先安装nuget包

Install Package NEST

 

1.创建索引

先建一个Model用于映射索引

 /// <summary>
    /// 商品信息
    /// </summary>
    public class OrderInfo
    {
        public string Id { get; set; } 
        public DateTime CreateTime { get; set; }
        public string Name { get; set; }
        public string GoodsName { get; set; }

        public string Status { get; set; }
    }

1.1自动转换ES类型

    /// <summary>
    /// ES操作
    /// </summary>
    public class ESService
    {
        //创建连接client
        private static ElasticClient _client = new ElasticClient(new Uri("http://192.168.101.13:9200"));

        //创建索引mapping
        public void Mapping()
        {
            //创建索引,自动转换类型,order为索引名称
            _client.Indices.Create("order", c => c
             .Map<OrderInfo>(m => m
             .AutoMap()
             ));

        }
    }

得到order的mapping的为

 "order" : {
    "mappings" : {
      "properties" : {
        "createTime" : {
          "type" : "date"
        },
        "goodsName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "id" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "status" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }

1.2通过特性指定字段的ES类型

   /// <summary>
    /// 商品信息
    /// </summary>
    public class OrderInfo
    {
        [Keyword(Name="Id")]
        public string Id { get; set; }
        [Date(Name = "CreateTime")]
        public DateTime CreateTime { get; set; }
        [keyword]
        public string Name { get; set; }
        [Text]
        public string GoodsName { get; set; }

        public string Status { get; set; }
    }

通过给字段标特性指定字段转换成的ES类型,类型有:Text,Keyword,Number,Boolean,Date等

2.插入数据

 2.1.插入单条数据

 /// <summary>
        /// 插入单条
        /// </summary>
        public void Insert()
        {
            var order = new OrderInfo()
            {
                Id = Guid.NewGuid().ToString(),
                CreateTime = DateTime.Now,
                Name = "张三",
                GoodsName = "手机P50",
                Status = "购物车"
            };
            var indexResponse = _client.Index(order, i => i.Index("order"));
            if(!indexResponse.IsValid)
            {
                //插入失败处理
            }
        }

2.2批量插入数据

/// <summary>
        /// 插入多条
        /// </summary>
        public void InsertList()
        {
            var orders = new List<OrderInfo>();
            for(int i=1;i<=10;i++)
            {
                orders.Add(new OrderInfo()
                {
                    Id = Guid.NewGuid().ToString(),
                    CreateTime = DateTime.Now,
                    Name = "王五" + i,
                    GoodsName="冰箱"+i,
              Status="待付款"
                });
            }

            var bulkIndexResponse = _client.Bulk(b => b
              .Index("order")
              .IndexMany(orders));
            if(!bulkIndexResponse.IsValid)
            {
                //失败处理
            }
           
        }

3.数据查询

3.1查询全部数据

/// <summary>
        /// 查询全部
        /// </summary>
        public void SearchAll()
        {
            QueryContainer query = new QueryContainer();
            query = new MatchAllQuery(); //查询全部

             var searchResponse = _client.Search<OrderInfo>(s => s
              .Index("order")
              .Query(q=>query)
              );
            //获取查询数据
            List<OrderInfo> datas =searchResponse.Documents.ToList();
        }

3.2分页查询

 /// <summary>
        /// 分页查询
        /// </summary>
        public void SearchPage()
        {
            QueryContainer query = new QueryContainer();
            query = new MatchAllQuery(); //查询全部
            int pageIndex = 1;
            int pageSize = 5;

            var searchResponse = _client.Search<OrderInfo>(s => s
             .Index("order")
             .Query(q => query)
             .From((pageIndex-1)*pageSize) //从第几条索引开始
             .Size(pageSize) //返回多少条
             );
            //获取查询数据
            List<OrderInfo> datas = searchResponse.Documents.ToList();
        }

3.3游标查询Scroll

为了避免深度分页性能问题,ES默认From&Size的查询只能查询到10000条之前的数据,要查询10000条之后的数据,需要用到游标查询

第一次查询产生scrollId,后面的查询只需要scrollId就可以记住原来的条件和查询位置,往后滚动查询

  /// <summary>
        /// 游标查询
        /// </summary>
        public void SearchScroll()
        {
            MatchAllQuery query = new MatchAllQuery();//查询全部
            int pageSize = 5;

            var searchResponse = _client.Search<OrderInfo>(s => s
             .Index("order")
             .Query(q => query)
             .Size(pageSize) //一次返回多少条
             .Scroll("10s") //scrollId有效时间
             );
            //获取查询数据
            List<OrderInfo> datas = searchResponse.Documents.ToList();

           string scrollId = searchResponse.ScrollId;//游标Id
            //后面的查询只需要用scrollId查询
           var searchResponse2 = _client.Scroll<OrderInfo>("10s", scrollId);
           
            List<OrderInfo> datas2 = searchResponse2.Documents.ToList();

        }

3.4条件查询

 /// <summary>
        /// 条件查询
        /// </summary>
        public void SearchWhere()
        {
            //查询name=王五
            var searchResponse = _client.Search<OrderInfo>(s => s
            .Index("order")
                  .Query(q => q.Term(q=>q.Name, "王五1"))
          );
            //获取查询数据
            List<OrderInfo> datas = searchResponse.Documents.ToList();
        }

3.5条件or查询

/// <summary>
        /// 条件or查询
        /// </summary>
        public void SearchOr()
        {
           //查询 name='王五1'or name='王五二'
            var searchResponse = _client.Search<OrderInfo>(s => s
              .Index("order")
              .Query(q => q
              .Term(o=>o.Name,"王五1")||q
              .Term(o=>o.Name,"王五2"))
            );
            //获取查询数据
            List<OrderInfo> datas = searchResponse.Documents.ToList();
        }

 3.6条件And查询

 /// <summary>
        /// 条件and查询
        /// </summary>
        public void SearchAnd()
        {
            //查询 name='王五1'or status='待付款'
            var searchResponse = _client.Search<OrderInfo>(s => s
              .Index("order")
              .Query(q => q
              .Term(o => o.Name, "王五1") && q
              .Term("status.keyword", "待付款")) //因为status是text+keyword类型,查询字段要加上".keyword"
            );
            //获取查询数据
            List<OrderInfo> datas = searchResponse.Documents.ToList();
        }

 3.7聚合统计查询

  /// <summary>
        /// 聚合查询统计
        /// </summary>
        public void SearchAggs()
        {
            //求员工年龄平均值和最大年龄
            var searchResponse = _client.Search<object>(s => s
              .Index("employee")
              .Size(0) //不返回源数据
              .Aggregations(aggs=>aggs
              .Average("avgage",avg=>avg.Field("age"))
              .Max("maxage",max=>max.Field("age"))
            ));
            var datas = searchResponse.Aggregations ;
           

        }

3.8聚合分组查询

 /// <summary>
        /// 聚合分组查询
        /// </summary>
        public void SearchAggsGroup()
        {
            //求员工年龄平均值和最大年龄
            var searchResponse = _client.Search<object>(s => s
              .Index("employee")
              .Size(0) //不返回源数据
              .Aggregations(aggs => aggs
            .Terms("jobgroup", group => group.Field("job"))
            ));
            var datas = searchResponse.Aggregations;

        }

 4.sql语句查询

需要安装sql插件,参照前一篇文章,这里通过rest api向ES发起sql语句的查询

建一个参数类和HttpHelper

    public class QueryParam
    {
        public string query { get; set; }
    }
    public class HttpHelper
    {
        private static HttpClient _httpClient = new HttpClient();
        public static string Post(QueryParam param, string url)
        {
            HttpContent content = new StringContent(JsonConvert.SerializeObject(param));
            content.Headers.ContentType= new MediaTypeHeaderValue("application/json");
            string result = _httpClient.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
            content.Dispose();
            return result;
        }
    }

向ES发起sql语句查询

     /// <summary>
        /// sql语句查询
        /// </summary>
        public void SearchSql()
        {
            QueryParam queryParam = new QueryParam();
            queryParam.query = "select * from employee where job='java'";
            string url = "http://192.168.101.13:9200/_xpack/sql?format=csv";
            var result = HttpHelper.Post(queryParam, url);
            Console.WriteLine(result);
        }

 

 

 

 这里查询返回的格式为csv格式,数据需要自己解析成对象

 

 更多用法参考NEST官网:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/index.html

posted on 2022-02-14 10:11  包子wxl  阅读(2187)  评论(0编辑  收藏  举报