有没有办法让elasticsearch只返回 all 符合某些条件的嵌套对象的文档?说我有以下人为的例子:
"mappings": {
"person": {
"properties": {
"name": { "type": "string" },
"other_info": ...
"pet": {
"type": "nested",
"properties": {
"gender": { "type": "string" },
"age": { "type": "integer" },
"name": { "type": "string" },
"other_info": ...
}
}
}
}
}
在这种情况下,我如何搜索那些所有年龄大于5的宠物的人?我还想搜索与宠物无关的其他属性,但为了简单起见,我们假设不然。如果一个人有三只宠物但只有一只或两只超过5只,我不希望它出现在搜索中。
我找不到任何关于如何做到这一点,所以我考虑了一个我不喜欢的替代解决方案。不是使用嵌套文档,而是为宠物设置单独的索引,将人员ID作为属性(可能带有_parent
字段?)。然后我可以做以下事情:
这似乎是一种非常迂回的方式,但是如果我走这条路线,我需要知道每个人拥有的宠物总数,然后再查询人物索引(比如将它存储为每个人的财产)宠物,但这只是让它变得非常混乱)或搜索所有至少有一个匹配宠物的人,宠物计数提前存储在人物索引中(或使用script filter?),然后检查计数是否匹配。
我遇到了this github issue(添加了“返回匹配每次点击的嵌套内部对象”功能)这本来非常有用,但不幸的是它还没有实现。
当然有更好的方法吗?
答案 0 :(得分:6)
为什么不使用must_not
子句。如果我是你,我会在bool
过滤器中搜索一个年龄超过5的宠物的人,并使用must_not
条款搜索有5岁以下宠物的人。
像这样:
"filter" : {
"bool" : {
"must" : {
"nested" : {
"path" : "person.pet"
"filter" : {
"range" : {
"person.pet.age" : { "from" : 5 }
}
}
}
},
"must_not" : {
"nested" : {
"filter" : {
"range" : {
"person.pet.age" : { "lte" : 5 }
}
}
}
}
}
}
我在这里做的首先是让所有至少有一只5岁以上的宠物的人(其中包括有多只宠物的人,其中一些是年轻人)。然后我将所有5岁或以下宠物的人排除在外,留下所需的结果。
祝你好运!