使用elasticsearch匹配所有嵌套对象

时间:2013-09-18 02:27:19

标签: elasticsearch

有没有办法让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字段?)。然后我可以做以下事情:

  • 搜索5岁以上的宠物,结果获得宠物清单
  • 在应用程序端,按人ID将列表中的宠物分组
  • 计算每组中的宠物数量,如果这与该人拥有的宠物总数相匹配,请将该人员ID添加到列表中
  • 根据ID以及我要检查的任何其他特定于人的属性对人员索引进行另一次搜索

这似乎是一种非常迂回的方式,但是如果我走这条路线,我需要知道每个人拥有的宠物总数,然后再查询人物索引(比如将它存储为每个人的财产)宠物,但这只是让它变得非常混乱)或搜索所有至少有一个匹配宠物的人,宠物计数提前存储在人物索引中(或使用script filter?),然后检查计数是否匹配。

我遇到了this github issue(添加了“返回匹配每次点击的嵌套内部对象”功能)这本来非常有用,但不幸的是它还没有实现。

当然有更好的方法吗?

1 个答案:

答案 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岁或以下宠物的人排除在外,留下所需的结果。

祝你好运!