如何使用Nest ElasticSearch过滤含特定枚举值的嵌套列表对象
问题描述
我正在为BoolQuery构建过滤器,响应对象结构如下:
responsObject : { innerObject : { myinnerObjectBoolProperty: Bool, myinnerObjectListProperty : [ { innerObjectType: myEnum, // otherProperties }, { innerObjectType: myEnum, // otherProperties } ] } , // other properties }
我通过返回IEnumerable<QueryContainer>的方法构建查询过滤器,将过滤器赋值给BoolQuery的Must属性,再将该BoolQuery分配给SearchRequest的Query属性,传入ElasticClient的Search方法:
var searchRequest = new SearchRequest() { Query = bQuery, // other assignments }; var response = client.Search<responsObject>(searchRequest);
其中布尔属性的过滤已正常实现:
if (filterValuesList.Contains("myBoolProperty", StringComparer.OrdinalIgnoreCase)) { var termQuery = new TermQuery() { Field = "innerObject.myBoolProperty", Value = "true" }; queries.Add(termQuery); }
但尝试过滤包含特定枚举值的对象时,如下写法不生效:
var termQuery = new TermQuery() { Field = "innerObject.myinnerObjectListProperty.innerObjectType", Value = "certainType" };
我想要实现的效果等价于以下LINQ语句:
var result = responsObjects.Where(i =>i.innerObject.myinnerObjectListProperty.Any(p => p.innerObjectType == innerObjectType.CertainType));
请问如何正确实现该过滤逻辑?
解决方案
要实现等价于LINQ中Any的嵌套数组过滤逻辑,必须使用**NestedQuery**——因为Elasticsearch默认会将数组中的嵌套对象扁平化存储,直接用TermQuery无法正确识别数组中单个对象的条件匹配。
代码实现
var nestedQuery = new NestedQuery() { Path = "innerObject.myinnerObjectListProperty", // 指定嵌套对象的完整路径 Query = new BoolQuery() { Must = new List<QueryContainer> { new TermQuery() { Field = "innerObject.myinnerObjectListProperty.innerObjectType", Value = "certainType" // 注意:需与索引中存储的枚举格式一致(大小写、字符串/数字) } } }, // 可选:如需查看匹配的嵌套对象,配置InnerHits;仅过滤父文档可省略 InnerHits = new InnerHits() { Size = 1 } }; queries.Add(nestedQuery);
关键细节
NestedQuery的作用
它会告诉Elasticsearch将数组中的每个嵌套对象视为独立文档,确保只有当数组中存在至少一个对象满足条件时,父文档才会被筛选出来,完全对应LINQ中Any的逻辑。枚举值匹配校验
- 如果枚举按字符串存入索引,需保证
Value的大小写、拼写与索引中的一致(比如索引中是"CertainType"就不能写"certainType") - 如果枚举按数字存储,要传入枚举对应的数值(例如
innerObjectType.CertainType.ToString("D"))
- 如果枚举按字符串存入索引,需保证
InnerHits配置
若需要在返回结果中看到具体是哪个嵌套对象匹配了条件,可通过InnerHits设置返回数量;仅需过滤父文档时,可省略该配置或设Size = 0。
内容的提问来源于stack exchange,提问作者Mohamad Hammash
相关产品推荐
相关产品推荐

