在Elasticsearch中查询唯一术语集的聚合桶

pn9klfpd  于 2023-05-28  发布在  ElasticSearch
关注(0)|答案(1)|浏览(197)

给定以下索引:

PUT /example
{
  "mappings": {
    "properties": {
      "tags": {
        "type": "keyword"
      }
    }
  }
}

POST example/_bulk
{ "create" : { "_index" : "example" } }
{ "tags" : ["a", "b"] }
{ "create" : { "_index" : "example" } }
{ "tags" : ["c", "d"] }
{ "create" : { "_index" : "example" } }
{ "tags" : ["e"] }
{ "create" : { "_index" : "example" } }
{ "tags" : ["c", "d"] }

我希望按唯一的标记集而不是按包含标记的所有文档来聚合它们。类似于多项聚合,但查看一个字段。所以我想得到的答案是这样的:

{
  ...
  "aggregations" : {
    "tags" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [                       
        {
          "key" : ["a", "b"],
          "key_as_string" : "a|b",
          "doc_count" : 1
        },
        {
          "key" : ["c", "d"],
          "key_as_string" : "c|d",
          "doc_count" : 2
        },
        {
          "key" : ["e"],
          "key_as_string" : "e",
          "doc_count" : 1
        }
      ]
    }
  }
}

我知道实现这一点的一种方法是创建另一个字段,该字段是所有标记的排序字符串,然后在该字段上进行聚合,但我只是想知道这是否可能。我的真实的用例稍微复杂一些,使用嵌套字段,所以我希望避免添加新字段。

0yg35tkg

0yg35tkg1#

试试这个:

PUT test_example
{
  "mappings": {
    "properties": {
      "tags": {
        "type": "keyword"
      }
    }
  }
}

POST _bulk?refresh
{ "create" : { "_index" : "test_example" } }
{ "tags" : ["a", "b"] }
{ "create" : { "_index" : "test_example" } }
{ "tags" : ["c", "d"] }
{ "create" : { "_index" : "test_example" } }
{ "tags" : ["e"] }
{ "create" : { "_index" : "test_example" } }
{ "tags" : ["c", "d"] }

POST test_example/_search
{
  "size": 0,
  "aggregations": {
    "tags": {
      "terms": {
        "script": {
          "source": "String.join('|', params._source.tags)",
          "lang": "painless"
        },
        "collect_mode": "breadth_first",
        "execution_hint": "map"
      }
    }
  }
}

编辑

如果你想保住c| d”和“d| c”在同一个桶中,您可以使用自定义,并且可以在搜索期间使用自定义脚本手动排序标签。下面是一个更新的查询:

POST _bulk?refresh
{ "create" : { "_index" : "test_example2" } }
{ "tags" : ["c", "d"] }
{ "create" : { "_index" : "test_example2" } }
{ "tags" : ["d", "c"] }

POST test_example2/_search
{
  "size": 0,
  "aggregations": {
    "tags": {
      "terms": {
        "script": {
          "source": """
            def sortedTags = params._source.tags.stream().sorted().collect(Collectors.toList());
            String.join('|', sortedTags)
          """,
          "lang": "painless"
        },
        "collect_mode": "breadth_first",
        "execution_hint": "map"
      }
    }
  }
}

相关问题