使用elasticsearch匹配所有嵌套对象

Wal*_*fie 1 elasticsearch

有没有办法让elasticsearch只返回所有嵌套对象符合某些条件的文档?说我有以下人为的例子:

"mappings": {                                                                                                                                                            
  "person": {                                                                                                                                                            
    "properties": {                                                                                                                                                      
      "name": { "type": "string" },                                                                                                                                       
      "other_info": ...                                                                                                                                                  

      "pet": {                                                                                                                                                      
        "type": "nested",                                                                                                                                                 
        "properties": {                                                                                                                                                  
          "gender": { "type": "string" },                                                                                                                                 
          "age": { "type": "integer" },                                                                                                                                   
          "name": { "type": "string" },                                                                                                                                   
          "other_info": ...                                                                                                                                              
        }                                                                                                                                                                
      }                                                                                                                                                                  
    }                                                                                                                                                                    
  }                                                                                                                                                                      
}    
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我将如何寻找谁拥有宠物的人具有的年龄大于5?我还想搜索与宠物无关的其他属性,但为了简单起见,我们假设不然.如果一个人有三只宠物但只有一只或两只超过5只,我不希望它出现在搜索中.


我找不到任何关于如何做到这一点,所以我考虑了一个我不喜欢的替代解决方案.而不是使用嵌套文档,为宠物提供单独的索引,将人员ID作为属性(可能带有_parent字段?).然后我可以做以下事情:

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

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

我遇到了这个github问题(添加了"返回匹配每次命中的嵌套内部对象"这一特性),这本来是非常有用的,但不幸的是它还没有实现.

当然有更好的方法来做到这一点?

ram*_*laf 6

为什么不使用一个must_not条款.如果我是你,我会搜索一个5岁以上宠物的人和bool一个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 }
                    }
                } 
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里做的是首先让所有至少有一只5岁以上的宠物的人(其中包括有多只宠物的人,其中一些是年轻的).然后我将所有5岁或以下宠物的人排除在外,留下所需的结果.

祝好运!