elasticsearch 聚合字符串数组

elasticsearch aggregate array of strings

我需要一个聚合查询来获取包含我所有根文件夹的存储桶。我的 elasticsearch 中的所有文档都有一个名为 path 的字段,我在其中存储一个数组,其中包含文档所在的路径(例如 path=[1.3., 1.2.4, 5., 11] ).

如果我使用正常的术语聚合

"terms": {
    "field": "path.keyword"
}

不幸的是我得到了所有唯一路径:

"buckets" : [
    {
      "key" : "1.3."
      "doc_count" : 6
    },
    {
      "key" : "11."
      "doc_count" : 3
    },
    {
      "key" : "5."
      "doc_count" : 3
    },
    {
      "key" : "1.2.4."
      "doc_count" : 1
    }
]

我尝试使用无痛脚本解决它

"terms": {
    "script": "doc['path.keyword'].value.substring(0, doc['path.keyword'].value.indexOf('.')  )"
}

但后来我只得到路径数组的最后一个元素

"buckets" : [
    {
      "key" : "1",
      "doc_count" : 7
    },
    {
      "key" : "11",
      "doc_count" : 3
    }
]

如何只获取根文件夹?

使用 doc["field"].value 将给出字段中所有值的单个字符串。 在脚本中,您需要 return 具有根值的值数组,即遍历字段的所有元素和 return 子字符串数组。

示例数据:

"hits" : [
      {
        "_index" : "index84",
        "_type" : "_doc",
        "_id" : "yihhWnEBHtQEPt4DqWLz",
        "_score" : 1.0,
        "_source" : {
          "path" : [
            "1.1.1",
            "1.2",
            "2.1.1",
            "12.11"
          ]
        }
      }
    ]

查询

{
  "aggs": {
    "root_path": {
      "terms": {
        "script": {
          "source": "def firstIndex=0;def path=[]; for(int i=0;i<doc['path.keyword'].length;i++){firstIndex=doc['path.keyword'][i].indexOf('.'); path.add(doc['path.keyword'][i].substring(0,firstIndex))} return path;"
        }
      }
    }
  }
}

结果:

"aggregations" : {
    "root_path" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "1",
          "doc_count" : 1
        },
        {
          "key" : "12",
          "doc_count" : 1
        },
        {
          "key" : "2",
          "doc_count" : 1
        }
      ]
    }
  }