在弹性搜索中查询多个嵌套对象,以获得所有嵌套对象中的一个和非另一个的非先行性

时间:2016-04-20 19:31:17

标签: elasticsearch

在elasticsearch 2.3上运行

我有一个foos索引。每个foo都有0个或更多个存储在嵌套对象中的条。每个条形都有0个或更多具有名称和值的属性。

使用https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-query.html

上的文档

将查询写入:

非常简单
  • 返回至少有1 bar.name = "sandwich" OR
  • 的所有foos
  • 返回所有没有bar.name = "pizza"
  • 的foos

我似乎无法弄清楚如何编写一个返回所有foos的查询:

  • 至少有1 bar.name = "sandwich" AND
  • 没有bar.name = "pizza"

我对这个问题的反对时间超过了我承认的时间。任何帮助表示赞赏。

详细说明:

foo有2个属性:

  • foo_id:一个数字
  • bar:存储为嵌套文档的0个或更多条形的列表

一个酒吧有2个属性:

  • bar_id:一个数字
  • properties:0个或更多kv对的列表。

剥离映射。真正的节目与食物无关。

{
  "some_index" : {
    "mappings" : {
      "foo" : {
        "properties" : {
          "bar" : {
            "type" : "nested",
            "properties" : {
              "bar_id" : {
                "type" : "long"
              },
              "details" : {
                "properties" : {
                  "name" : {
                    "type" : "string"
                  },
                  "value" : {
                    "type" : "long"
                  }
                }
              }
            }
          },
          "foo_id" : {
            "type" : "long",
            "index" : "not_analyzed",
            "store" : true
          }
        }
      }
    }
  }
}

没有披萨的典型foo

# this one does have a bar.name = sandwich
# this one doesn't have pizza for ANY bars
# this would match the query
{
        "foo_id": 186456,
        "bar": [
        {
                "bar_id": 1056791,
                        "details": [
                        {
                                "name": "taco",
                                "value": 2
                        },
                        {
                                "name": "sandwich",
                                "value": 1
                        }
                ]
        },
        {
                "bar_id": 1056800,
                "details": [
                {
                        "name": "sandwich",
                        "value": 0
                }
                ]
        }
        ]

}

带有一些披萨的典型foo

# this one has a bar.name = sandwich
# this one has pizza for some bars, but not all of them
# this would NOT match the query
    {
            "foo_id": 187390,
            "bar": [
            {
                    "bar_id": 1057455,
                            "details": [
                            {
                                    "name": "taco",
                                    "value": 1
                            }
                    ]
            },
            {
                    "bar_id": 1057457,
                    "details": [
                    {
                            "name": "taco",
                            "value": 0
                    },
                    {
                            "name": "sandwich",
                            "value": 1
                    }
                    ]
            },
            {
                    "bar_id": 1057458,
                    "details": [
                    {
                            "name": "sandwich",
                            "value": 1
                    },
                    {
                            "name": "pizza",
                            "value": 0
                    }
                    ]
            }
            ]

    }

1 个答案:

答案 0 :(得分:1)

bar include_in_parent字段设为true

    "bar": {
      "type": "nested",
      "include_in_parent": true, 
      "properties": {
        "bar_id": {
          "type": "long"
        },
        "details": {
          "properties": {
            "name": {
              "type": "string"
            },
            "value": {
              "type": "long"
            }
          }
        }
      }
    }

并使用此查询:

{
  "query": {
    "query_string": {
      "query": "bar.details.name:(sandwich NOT pizza)"
    }
  }
}