2016-01-22 222 views
4

我是Elasticsearch的新手,我试图创建一个过滤器来检索具有特定属性的文档。Elasticsearch嵌套对象过滤器

的属性定义为嵌套对象的映射,像这样:

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

我想要的形式执行复杂查询:

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

据我所阅读到目前为止我已创建以下查询以es:

{ 
    "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" } 
    } 
} 

但是,这不会返回任何重新sults。如果我删除must块中的两个bools中的一个,它会正确过滤文档。

存在同样的问题(没有结果),如果我更改查询(用于测试目的)到:

"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版本我做错了什么?

+0

也许每个'bool'子句可以在它自己的'nested'子句中?而不是将它们全部包装在一起。 –

+0

@EvaldasBuinauskas我会尽力回复你。 – mobius

+0

你可以发布一个你期望被这个查询返回的示例文档吗? – goalie7960

回答

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的一部分表示:

该查询针对嵌套对象执行/文档,就好像它们 被索引为单独的文档(它们是,在内部),并产生 根父doc(或父嵌套映射)。

当做nested查询,你实际上并没有对根文档进行查询(尽管它感觉这种方式)。该查询针对嵌套文档进行操作,就好像它们是单独的文档一样。

因此,当查询针对具有 ID =一个嵌套文件(1或2)和ID =(3或4)你没有结果。在您的数据中,每个嵌套文档都只有这些id值中的一个。

+0

你是对的! (就像@EvaldasBuinauskas在上面的评论中指出的那样)最让我困惑的是,让一个单人应该在一个必须布尔内工作的事实。 – mobius

+0

非常感谢。它非常清楚。很好的帮助。 –