如何在ElasticSearch中查询一个数组中的两个字段和数组中的同一元组?

daj*_*ood 4 elasticsearch

假设我的索引中有一些文档,如下所示:

{
  "category":"2020",
  "properties":[
    {
     "name":"foo",
     "value":"2"
    },
    {
     "name":"boo",
     "value":"2"
    }
  ]
},
{     
  "category":"2020",
  "properties":[
    {
     "name":"foo",
     "value":"8"
    },
    {
     "name":"boo",
     "value":"2"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我想以仅返回那些匹配"foo":"2"但不匹配的文档的方式查询索引"boo":"2"

我尝试编写一个与properties.name 和 都 properties.value匹配的查询,但随后出现误报。我需要一种方法来告诉 ElasticSearch 名称和值必须属于同一属性元组。

我怎样才能做到这一点?

Val*_*Val 5

您需要将其映射propertiesnested类型。所以你的映射看起来类似于:

{
  "your_type": {
    "properties": {
      "category": {
        "type": "string"
      },
      "properties": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,您的查询要匹配包含"foo=2"在同一元组中但不在"boo=2"同一元组中的文档,则需要相应地使用该nested查询,如下所示。

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "properties",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "properties.name": "foo"
                    }
                  },
                  {
                    "match": {
                      "properties.value": "2"
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "must_not": [
        {
          "nested": {
            "path": "properties",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "properties.name": "boo"
                    }
                  },
                  {
                    "match": {
                      "properties.value": "2"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)