Elasticsearch查询帮助 - 多个嵌套AND / OR

时间:2015-09-25 21:06:43

标签: elasticsearch

我正在努力使用elasticsearch过滤器。我有company_office类型,如下所示:

{
  "company_office_id": 1,
  "is_headquarters": true,
  "company": {
    "name": "Some Company Inc"
  },
  "attribute_values": [
      {
        "attribute_id": 1,
        "attribute_value": "attribute 1 value",
      },
      {
        "attribute_id": 2,
        "attribute_value": "ABC",
      },
      {
        "attribute_id": 3,
        "attribute_value": "DEF",
      },
      {
        "attribute_id": 3,
        "attribute_value": "HIJ",
      }
  ]
}

我们假设attribute_value是 not_analyzed - 所以我可以完全匹配它。

现在我想过滤多个attribute_id和value字段的组合。 SQL中的这样的东西:

SELECT *
FROM CompanyOffice c
JOIN Attributes a --omitting the ON here, just assume the join is valid
WHERE 
c.is_headquarters = true AND
(
  (a.attribute_id=2 AND a.attribute_value IN ('ABC')) OR
  (a.attribute_id=3 AND a.attribute_value IN ('DEF','HIJ')) 
)

所以我需要过滤特定字段+多个ID /值组合。

这是我试过的查询:

{
  "query" : {
    "filtered" : {
      "filter" : {
        "bool" : {
          "must" : [


            { "term": {"is_headquarters": true } },
            {"bool": { 
                      "must":[
                        {"term": {"attribute_values.attribute_id": 1}},
                        {"bool": { "should": [{"term": {"attribute_values.attribute_value": "HIJ"}}]}}
                      ]
                     }}          
          ] 
        } 
      } 
    } 
  } 
}

即使company_office没有1 /' HIJ'的任何id / value配对,此查询也会返回结果。我的想法是因为这个bool过滤器位于父must部分内,所以所有项都必须为真:

            {"bool": { 
                      "must":[
                        {"term": {"attribute_values.attribute_id": 1}},
                        {"bool": { "should": [{"term": {"attribute_values.attribute_value": "HIJ"}}]}}
                      ]
                     }}  

为什么在查询问题开头提供的数据样本时,此查询会返回结果?有没有不同的方法来编写过滤器并完成我想要做的事情?

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

如果要查询更深层的对象而不展平其结构,则需要设置

"type": "nested"

"attribute_values"财产上。

然后参考如何编写nested queries in documentation,你应该正确检索整个文档。使用inner hits检索匹配的attribute_values

默认情况下,Elasticsearch在索引时不会嵌套属性。所有子字段都被压缩到单独的子字段中,无法按实际结构查询它们。您将看不到此效果,因为会返回原始文档。

除此之外,您的查询有点偏。在上一个"should"语句中,您只有一个术语过滤器,因此它实际上是"must"部分,但它们必须重写为嵌套格式。