我们如何只对 Elasticsearch 上匹配的前缀进行聚合?

How do we bucket aggregate only on the matched prefix on Elasticsearch?

我在 Elaticsearch 上索引了一些文档,其中一个文档字段是 "users",这是一个用户数组。现在我尝试为每个用户查找用户名与某些前缀匹配的文档。前缀用于过滤文档。但我希望 returned 桶也可以通过相同的前缀进行过滤。有没有办法做到这一点?下面的示例解释了这个问题。

创建索引test1:

curl -XPUT 'http://localhost:9200/test1/'

在索引 test1 中为类型 type1 创建 9 个文档:

    i=1
while [ $i -lt 10 ] ; do

    curl -XPUT "localhost:9200/test1/type1/$i" -d '{
        "users" : ["ram", "hari", "balu"]
    }'
    i=`expr $i + 1`
done

现在 运行 每个用户的文档聚合,其中用户名匹配前缀 "ra"

curl -XPOST 'localhost:9200/test1/type1/_search?pretty' -d '
{
  "size" : 0,
  "aggs": {
    "prefix_match_aggr": {
        "filter" : { "prefix" : {"users" : "ra"}},
        "aggs" : {
            "actual_aggr" : {
                "terms": {
                    "field" : "users",
                    "size" : 0
                }
            }
        }
      }
    }
}'

聚合 return 如下:

{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 9,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "prefix_match_aggr" : {
      "doc_count" : 9,
      "actual_aggr" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [ {
          "key" : "balu",
          "doc_count" : 9
        }, {
          "key" : "hari",
          "doc_count" : 9
        }, {
          "key" : "ram",
          "doc_count" : 9
        } ]
      }
    }
  }
}

正如我们所见,它return为所有用户 balu、hari 和 ram 编辑了存储桶。有没有办法只 return 匹配前缀 "ra" 的桶,即 ram、rami、raman 等的桶?

其实我已经找到答案了。术语聚合必须使用 "include" 字段,因此现在的查询将是:

curl -XPOST 'localhost:9200/test1/type1/_search?pretty' -d '
{
  "size" : 0,
  "aggs": {
    "prefix_match_aggr": {
        "filter" : { "prefix" : {"users" : "ra"}},
        "aggs" : {
            "actual_aggr" : {
                "terms": {
                    "field" : "users",
                    "include" : "ra.*",
                    "size" : 0
                }
            }
        }
      }
    }
}'