【问题标题】:ElasticSearch: find multiple unique values in array with complex objectsElasticSearch:在具有复杂对象的数组中查找多个唯一值
【发布时间】:2020-04-16 18:37:35
【问题描述】:

假设有一个索引,其文档结构如下:

{
    "array": [
        {
            "field1": 1,
            "field2": 2
        },
        {
            "field1": 3,
            "field2": 2
        },
        {
            "field1": 3,
            "field2": 2
        },
        ...
    ]
}

是否可以定义一个查询来返回一个字段具有多个唯一值的文档?

对于上面的示例,在 field2 上搜索的查询不会返回文档,因为它们都具有相同的值,但在 field1 会返回它,因为它的值是 1 和 3。

我唯一能想到的是将唯一值存储在父对象中,然后查询它的长度,但是,因为它看起来微不足道,我希望在不必将结构更改为类似的情况下解决它:

{
    "arrayField1Values" : [1, 3],
    "arrayField2Values" : [2]
    "array": [
        {
            "field1": 1,
            "field2": 2
        },
        {
            "field1": 3,
            "field2": 2
        },
        {
            "field1": 3,
            "field2": 2
        },
        ...
    ]
}

感谢任何可以提供帮助的人!

【问题讨论】:

  • 如果某个字段的值在文档中仅出现一次,您希望返回该字段。因此,如果一个字段存在于多个文档中,则不返回它,或者如果它存在于所有文档中,则不返回?

标签: elasticsearch elasticsearch-query


【解决方案1】:

我的直觉是使用 nested 数据类型,但后来我意识到您可以使用 query scriptstop_hits 对字段 1 和 2 的数组值进行简单的不同计数:

PUT array

POST array/_doc
{
  "array": [
    {
      "field1": 1,
      "field2": 2
    },
    {
      "field1": 3,
      "field2": 2
    },
    {
      "field1": 3,
      "field2": 2
    }
  ]
}

GET array/_search
{
  "size": 0,
  "aggs": {
    "field1_is_unique": {
      "filter": {
        "script": {
          "script": {
            "source": "def uniques = doc['array.field1'].stream().distinct().sorted().collect(Collectors.toList()); return uniques.length > 1 ;",
            "lang": "painless"
          }
        }
      },
      "aggs": {
        "top_hits_field1": {
          "top_hits": {}
        }
      }
    },
    "field2_is_unique": {
      "filter": {
        "script": {
          "script": {
            "source": "def uniques = doc['array.field2'].stream().distinct().sorted().collect(Collectors.toList()); return uniques.length > 1 ;",
            "lang": "painless"
          }
        }
      },
      "aggs": {
        "top_hits_field2": {
          "top_hits": {}
        }
      }
    }
  }
}

针对 field1field2 是否包含 > 1 的唯一值计数产生单独的聚合:

 "aggregations" : {
    "field1_is_unique" : {
      "doc_count" : 1,
      "top_hits_field1" : {
        "hits" : {
          "total" : {
            "value" : 1,
            "relation" : "eq"
          },
          "max_score" : 1.0,
          "hits" : [
            {
              "_index" : "array",
              "_type" : "_doc",
              "_id" : "WbJhgnEBVBaNYdXKNktL",
              "_score" : 1.0,
              "_source" : {
                "array" : [
                  {
                    "field1" : 1,
                    "field2" : 2
                  },
                  {
                    "field1" : 3,
                    "field2" : 2
                  },
                  {
                    "field1" : 3,
                    "field2" : 2
                  }
                ]
              }
            }
          ]
        }
      }
    },
    "field2_is_unique" : {
      "doc_count" : 0,
      "top_hits_field2" : {
        "hits" : {
          "total" : {
            "value" : 0,
            "relation" : "eq"
          },
          "max_score" : null,
          "hits" : [ ]
        }
      }
    }
  }

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-13
    • 2012-06-19
    • 2020-04-05
    • 2020-12-19
    • 2019-02-26
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    相关资源
    最近更新 更多