Elasticsearch嵌套对象过滤器

时间:2016-01-22 12:51:51

标签: elasticsearch

我是Elasticsearch的新手,我正在尝试创建一个过滤器来检索具有特定属性的文档。

属性在映射中定义为嵌套对象,如下所示:

"attributes": {
  "type": "nested",
    "properties" : {
      "id": {
        "type": "integer"
      },
      ...
    }
  }
}

我试图以以下形式执行复杂查询:

(attribute.id == 1 OR attribute.id == 2) AND (attribute.id == 3 OR attribute.id == 4)

根据我到目前为止所读到的内容,我已经创建了以下查询:

{
  "query": {
    "filtered": {
     "query": {
        "match_all": {}
     },
     "filter": {
        "nested": {
           "path": "attributes",
           "filter": {
              "bool": {
                "must": [
                    { "bool" : {
                      "should" : [
                        { "term": { "attributes.id": 1 }},
                        { "term": { "attributes.id": 2 }}
                      ]
                    }},
                    { "bool" : {
                      "should" : [
                        { "term": { "attributes.id": 3 }},
                        { "term": { "attributes.id": 4 }}
                      ]
                    }}
                ]
              }
           }
        }
     }
  }
},
"sort": {
    "date": { "order": "desc" }
  }
}

然而,这不会返回任何结果。如果我删除bools块中的两个must之一,则会正确过滤文档。

如果我将查询(出于测试目的)更改为:

,则存在相同的问题(无结果)
"must": [
  { "term": { "attributes.id": 3 }},
  { "bool" : {
    "should" : [
      { "term": { "attributes.id": 1 }},
      { "term": { "attributes.id": 2 }}
    ]
  }}
]

我的理解转化为attributes.id == 3 AND (attributes.id == 1 OR attributes.id == 2)

这是elasticsearch 2.x.我做错了什么?

1 个答案:

答案 0 :(得分:3)

为了获得您要查找的结果,您需要执行两个单独的nested个查询,并使用bool查询将它们链接在一起。

以下是一个例子:

{
  "bool":{
    "must":[
      {
        "nested":{
          "path":"attributes",
          "filter":{
            "bool":{
              "should":[
                { "term": {"attributes.id": 1 }},
                { "term": {"attributes.id": 2 }}
              ]
            }
          }
        }
      },
      {
        "nested":{
          "path":"attributes",
          "filter":{
            "bool":{
              "should":[
                { "term": {"attributes.id": 3 }},
                { "term": {"attributes.id": 4 }}
              ]
            }
          }
        }
      }
    ]
  }
}

原因在于嵌套文档和嵌套查询的细微差别。看一下documentation on nested queries的部分内容:

  

对嵌套对象/文档执行查询,就像它们一样   被索引为单独的文档(它们是内部的)并导致   根父文档(或父嵌套映射)。

执行nested查询时,您实际上并未对根文档执行查询(尽管感觉那样)。该查询针对嵌套文档进行操作,就像它们是单独的文档一样

因此,当您查询两者 id =(1或2)AND id =(3或4)的嵌套文档时,您将得不到任何结果。在您的数据中,每个嵌套文档只有这些id值中的一个。