扩展 Elasticsearch 客户端简化 ES 查询 (.net core/framework)
发布于: 1 小时前
扩展 Elasticsearch 客户端简化 ES 查询(.net core/framework)
Elasticsearch .net 客户端提供了两种方式进行查询操作
基于对象构造查询
new IdsQuery{ Name = "named_query", Boost = 1.1, Values = new List<Id> { 1, 2, 3, 4 },}
复制代码
基于 lambda 语法查询
q.Ids(c => c .Name("named_query") .Boost(1.1) .Values(1, 2, 3, 4))
复制代码
两种方式各有优缺点,最主要原因是条件稍有点复杂后,感觉像在套娃,一层套一层,特别是 lambda
如:
var searchResults = this.Client.Search<Project>(s => s .Query(q => q .Bool(b => b .Should( bs => bs.Term(p => p.Name, "x"), bs => bs.Term(p => p.Name, "y") ) ) ));
复制代码
官方文档有简化的写法,[Writing bool queries | Elasticsearch.Net and NEST: the .NET clients 7.x] | Elastic
但是这种方法式的调用还是很麻烦,避免不了方法组合
对于一般逻辑查询,通过运算符(d,!=,>,<)处理会更简洁
以下示例 ES 版本为 7.x
安装 nuget 包:CRL.Elasticsearch
using CRL;using CRL.Elasticsearch;
定义数据源
var builder = DBConfigRegister.GetInstance(); builder.UseElasticsearch(); builder.RegisterDBAccessBuild(dbLocation => { var dBAccessBuild= new DBAccessBuild(DBType.ES, "http://127.0.0.1:9200/testIndex"); //定义连接设置 Func<ConnectionSettings, ConnectionSettings> func = (setting) => { setting.DefaultMappingFor<GoodsInfo>(m => m.IndexName("testIndex")); setting.DefaultMappingFor<GoodsInfoChild>(m => m.IndexName("testIndex")); return setting; }; dBAccessBuild.Data = func; return dBAccessBuild; });
复制代码
定义查询对象
public class GoodsService:BaseProvider<GoodsInfo>{}
复制代码
初始数据
public static void CreateMapping() { var service = new GoodsService(); service.DropTable(); service.CreateEsIndex(); var list = new List<GoodsInfo>(); for (int i = 1; i < 11; i++) { list.Add(new GoodsInfo { Id = i.ToString(), DataType = "Goods", Name = "goods" + i, Number = i }); } service.BatchInsert(list); var service2 = new GoodsInfoChildService(); var childs = new List<GoodsInfoChild>(); childs.Add(new GoodsInfoChild("1", "100", "History") { GroupCode = "001" }); childs.Add(new GoodsInfoChild("1", "200", "History") { GroupCode = "001" }); service2.BatchInsert(childs);
}
复制代码
按逻辑查询
var service = new GoodsService();var list = service.QueryList(b => b.DataType == "Goods" && b.Id != "2");Console.WriteLine($"count should 9 {list.Count == 9}");
复制代码
对结果进行分组
public static void testAggregationCount() { var service = new GoodsService(); var query = service.GetLambdaQuery(); query.Where(b => b.DataType == "Goods"); query.GroupBy(b => new { b.DataType, b.Name }); var list = query.ToAggregationCount(); Console.WriteLine($"count should 2 {list.Count == 2}"); }
复制代码
指定查询方法
public static void testMethodAll() { var service = new GoodsService(); var query = service.GetLambdaQuery(); var ids = new List<Id>(); ids.Add("1"); query.Where(b => b.WithIdsQuery(ids)); query.Where(b => b.Name.WithWildcardQuery("goods*")); query.Where(b => b.Name.WithTermQuery("goods")); query.Where(b => b.Name.WithMatchQuery("goods", Operator.And)); query.Where(b => b.Name.WithMatchPhraseQuery("goods")); query.Where(b => b.WithMultiMatchQuery(new string[] { "Name", "DataType" }, "goods", Operator.And, TextQueryType.BestFields)); query.Where(b => b.WithQueryBase(new WildcardQuery { Field = "Name", Value = "goods" })); }
复制代码
子查询判断
public static void testChildQuery() { var service = new GoodsService(); var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods"); var queryChild = query.CreateQuery<GoodsInfoChild>(); queryChild.Where(b => b.GroupCode == "001"); query.HasChild(queryChild); var list = query.ToList(); Console.WriteLine($"count should 1 {list.Count == 1}"); }
复制代码
源码示例参考
划线
评论
复制
发布于: 1 小时前阅读数: 2
Spook
关注
还未添加个人签名 2021.06.24 加入
还未添加个人简介











评论