### 扩展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)