如何将DSL聚合查询转换为NEST Elasticsearch客户端C#查询?
Elasticsearch DSL转NEST C#客户端完整实现
问题背景
之前在前端编写了如下Elasticsearch DSL聚合查询,架构升级后需要改用C#端的NEST Elasticsearch客户端实现。已完成部分C#代码,但在实现los_counts聚合下嵌套的los filters聚合的子过滤器时受阻,请求完成完整查询转换。
前端DSL查询代码
{ "query": { "query_string": { "fields": [ "siteId" ], "query": "SE0*" } }, "aggs": { "total": { "cardinality": { "field": "linkId.keyword" } }, "los_counts": { "terms": { "field": "linkId.keyword", "size": "10000" }, "aggs": { "los": { "filters": { "filters": { "los_true": { "match": { "losFlag": "Y" } }, "los_false": { "bool": { "must_not": { "match": { "losFlag": "Y" } } } } } } } } } }, "collapse": { "field": "linkId.keyword" } }
已编写的C#代码片段
await _elasticClient.SearchAsync<T>(s => s .Index(indexName) .Take(10000) .Query(q => (q .MultiMatch(m => m .Fields(["siteId"]) .Query("SE0") ))) .Aggregations(ag => ag .Cardinality("total", ca => ca.Field("linkId.keyword")) .Terms("los_counts",tr=>tr.Field("linkId.keyword") .Aggregations(agg=>agg.Filters("los",fi=>fi.)) /* 此处卡住,不知如何实现子filters */ ) ) .Collapse(col => col.Field("linkId.keyword")) ).ConfigureAwait(false);
完整转换后的C#代码
await _elasticClient.SearchAsync<T>(s => s .Index(indexName) .Take(10000) // 修正Query为QueryString,匹配DSL中的query_string语法,并补上通配符* .Query(q => q .QueryString(qs => qs .Fields(f => f.Field("siteId")) .Query("SE0*") ) ) .Aggregations(ag => ag // 保持total基数聚合不变 .Cardinality("total", ca => ca.Field("linkId.keyword")) // 实现los_counts的terms聚合,设置Size为10000匹配DSL .Terms("los_counts", tr => tr .Field("linkId.keyword") .Size(10000) // 嵌套los的filters聚合,实现两个子过滤器 .Aggregations(agg => agg .Filters("los", fi => fi .Filters(new Dictionary<string, QueryContainer> { { "los_true", new MatchQuery { Field = "losFlag", Query = "Y" } }, { "los_false", new BoolQuery { MustNot = new List<QueryContainer> { new MatchQuery { Field = "losFlag", Query = "Y" } } } } }) ) ) ) ) .Collapse(col => col.Field("linkId.keyword")) ).ConfigureAwait(false);
关键修正点说明
- Query部分修正:原代码用了
MultiMatch,但DSL中是query_string,所以改用QueryString方法,并补上查询值的通配符*,和前端DSL保持一致。 - Terms聚合Size设置:DSL中
los_counts的terms聚合指定了size:10000,C#代码中需要通过.Size(10000)显式设置。 - Filters聚合实现:通过
Filters方法传入Dictionary<string, QueryContainer>,分别定义los_true和los_false两个过滤器,完全对应DSL中的子过滤规则。
内容的提问来源于stack exchange,提问作者abbas ahmed
相关产品推荐
相关产品推荐

