首页 > 解决方案 > 弹性搜索,对象数组的布尔查询

问题描述

该文档有一个这样的字段。

"device_versions": [
            {
              "name": "android",
              "min_major_ver": 3,
              "min_minor_ver": 54,
              "min_patch_ver": 0
            },
            {
              "name": "ios",
              "min_major_ver": 2,
              "min_minor_ver": 59,
              "min_patch_ver": 0
            }
          ]

我想写一个这样的查询

(device_versions.name = 'android' AND device_versions.min_major_ver = 3 AND device_versions.min_minor_ver = 55)

我写了以下查询-

"must": [
              {
                "term": {
                  "device_versions.name": "android"
                }
              },
              {
                "range": {
                  "device_versions.min_major_ver": {
                    "from": 3,
                    "include_lower": true,
                    "include_upper": true,
                    "to": null
                  }
                }
              },
              {
                "range": {
                  "device_versions.min_minor_ver": {
                    "from": 55,
                    "include_lower": true,
                    "include_upper": true,
                    "to": null
                  }
                }
              }
            ]

上述查询的问题是:最后一个范围查询与设备名称 = 'ios' 的数组元素匹配

我需要的是:在同一个数组元素上应用 3 个条件。设备 = "android" AND min_major_ver = 55 AND min_minor_ver = 55

标签: elasticsearch

解决方案


您的映射应该已启用嵌套,否则您的对象将变平

PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

将被存储为

{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

启用嵌套后,您的查询应该是

{
  "query": {
    "nested": {
      "path": "device_versions",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "device_versions.name": "android"
              }
            },
            {
              "range": {
                "device_versions.min_major_ver": {
                  "from": 3,
                  "include_lower": true,
                  "include_upper": true,
                  "to": null
                }
              }
            },
            {
              "range": {
                "device_versions.min_minor_ver": {
                  "from": 55,
                  "include_lower": true,
                  "include_upper": true,
                  "to": null
                }
              }
            }
          ]
        }
      }
    }
  }
}

推荐阅读