Elasticsearch使用系列-ES简介和环境搭建
Elasticsearch使用系列-ES增删查改基本操作+ik分词
Elasticsearch使用系列-基本查询和聚合查询+sql插件
Elasticsearch使用系列-.NET6对接Elasticsearch
先安装nuget包
Install Package NEST
1.创建索引
先建一个Model用于映射索引
////// 商品信息 /// 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类型
////// ES操作 /// 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 (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类型
////// 商品信息 /// 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.插入单条数据
////// 插入单条 /// 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批量插入数据
////// 插入多条 /// public void InsertList() { var orders = new List (); 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查询全部数据
////// 查询全部 /// public void SearchAll() { QueryContainer query = new QueryContainer(); query = new MatchAllQuery(); //查询全部 var searchResponse = _client.Search (s => s .Index("order") .Query(q=>query) ); //获取查询数据 List datas =searchResponse.Documents.ToList(); }
3.2分页查询
////// 分页查询 /// public void SearchPage() { QueryContainer query = new QueryContainer(); query = new MatchAllQuery(); //查询全部 int pageIndex = 1; int pageSize = 5; var searchResponse = _client.Search (s => s .Index("order") .Query(q => query) .From((pageIndex-1)*pageSize) //从第几条索引开始 .Size(pageSize) //返回多少条 ); //获取查询数据 List datas = searchResponse.Documents.ToList(); }
3.3游标查询Scroll
为了避免深度分页性能问题,ES默认From&Size的查询只能查询到10000条之前的数据,要查询10000条之后的数据,需要用到游标查询
第一次查询产生scrollId,后面的查询只需要scrollId就可以记住原来的条件和查询位置,往后滚动查询
////// 游标查询 /// public void SearchScroll() { MatchAllQuery query = new MatchAllQuery();//查询全部 int pageSize = 5; var searchResponse = _client.Search (s => s .Index("order") .Query(q => query) .Size(pageSize) //一次返回多少条 .Scroll("10s") //scrollId有效时间 ); //获取查询数据 List datas = searchResponse.Documents.ToList(); string scrollId = searchResponse.ScrollId;//游标Id //后面的查询只需要用scrollId查询 var searchResponse2 = _client.Scroll ("10s", scrollId); List datas2 = searchResponse2.Documents.ToList(); }
3.4条件查询
////// 条件查询 /// public void SearchWhere() { //查询name=王五 var searchResponse = _client.Search (s => s .Index("order") .Query(q => q.Term(q=>q.Name, "王五1")) ); //获取查询数据 List datas = searchResponse.Documents.ToList(); }
3.5条件or查询
////// 条件or查询 /// public void SearchOr() { //查询 name='王五1'or name='王五二' var searchResponse = _client.Search (s => s .Index("order") .Query(q => q .Term(o=>o.Name,"王五1")||q .Term(o=>o.Name,"王五2")) ); //获取查询数据 List datas = searchResponse.Documents.ToList(); }
3.6条件And查询
////// 条件and查询 /// public void SearchAnd() { //查询 name='王五1'or status='待付款' var searchResponse = _client.Search (s => s .Index("order") .Query(q => q .Term(o => o.Name, "王五1") && q .Term("status.keyword", "待付款")) //因为status是text+keyword类型,查询字段要加上".keyword" ); //获取查询数据 List datas = searchResponse.Documents.ToList(); }
3.7聚合统计查询
////// 聚合查询统计 /// 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聚合分组查询
////// 聚合分组查询 /// 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语句查询
////// sql语句查询 /// 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