【问题标题】:Querying multiple nested objects in elasticsearch for prescene of one and non prescence of another across all the nested objects在弹性搜索中查询多个嵌套对象,以查找所有嵌套对象中是否存在另一个对象
【发布时间】:2016-04-20 19:31:16
【问题描述】:

在弹性搜索 2.3 上运行

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

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

编写查询非常简单:

  • 返回所有至少有 1 个 bar.name = "sandwich" 或的 foos
  • 返回所有没有bar.name = "pizza"的foo

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

  • 至少有 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
                    }
                    ]
            }
            ]

    }

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    将您的bar 字段设置为include_in_parenttrue

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

    【讨论】:

    • 你正式成为我的英雄。上次我对 es 查询做任何严肃的事情是 0.9,不知何故我错过了所有变化的倾注。谢谢!
    • 不用担心 :-) 我很高兴能帮助你,这些事情有点棘手。您的要求与我过去处理的内容非常相似,因此很容易适应:stackoverflow.com/questions/26666037/….
    猜你喜欢
    • 1970-01-01
    • 2019-05-14
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多