扩展Elasticsearch客户端简化ES查询(.net core/framework)

2021-07-07 14:28:38 浏览数 (1)

### 扩展Elasticsearch客户端简化ES查询(.net core/framework)

Elasticsearch .net 客户端提供了两种方式进行查询操作

基于对象构造查询

```csharp

new IdsQuery

{

Name = "named_query",

Boost = 1.1,

Values = new List<Id> { 1, 2, 3, 4 },

}

```

基于lambda语法查询

```csharp

q

.Ids(c => c

.Name("named_query")

.Boost(1.1)

.Values(1, 2, 3, 4)

)

```

两种方式各有优缺点,最主要原因是条件稍有点复杂后,感觉像在套娃,一层套一层,特别是lambda

如:

```csharp

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](https://www.elastic.co/guide/en/elasticsearch/client/net-api/7.x/bool-queries.html)

但是这种方法式的调用还是很麻烦,避免不了方法组合

对于一般逻辑查询,通过运算符(d,!=,>,<)处理会更简洁

以下示例ES版本为7.x

1. 安装nuget包:CRL.Elasticsearch

2. using CRL;

using CRL.Elasticsearch;

**定义数据源**

```c#

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;

});

```

**定义查询对象**

```c#

public class GoodsService:BaseProvider<GoodsInfo>

{

}

```

**初始数据**

```c#

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);

}

```

**按逻辑查询**

```c#

var service = new GoodsService();

var list = service.QueryList(b => b.DataType == "Goods" && b.Id != "2");

Console.WriteLine($"count should 9 {list.Count == 9}");

```

**对结果进行分组**

```c#

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}");

}

```

**指定查询方法**

```c#

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"

}));

}

```

**子查询判断**

```c#

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}");

}

```

源码示例参考

[Data/esTest · hubroxxl/CRL - 码云 - 开源中国 (gitee.com)](https://gitee.com/hubroxxl/crl/tree/master/Data/esTest)

0 人点赞