弹性搜索聚合:“aggs”查询 - “字段”与“脚本” - 哪个更快?

时间:2016-06-09 13:48:48

标签: elasticsearch

根据“cityId”和“cityName”获取计数的聚合查询:

 "aggs": {
        "CityIdCount": {
          "terms": {
            "field": "cityId",
            "size": 0
          }
        },
        "CityNameCount": {
          "terms": {
            "field": "cityName",
            "size": 0
          }
        }
      }

使用脚本基于“cityId”和“cityName”获取计数的聚合查询:

"aggs": {
    "CityIdCount": {
      "terms": {
        "script": doc["cityId"] + doc["cityName"],
        "size": 0
      }
    }

如何在弹性内处理这些查询?哪个更快?

1 个答案:

答案 0 :(得分:1)

由于"size": 0,两者都很可怕,这表示它想要检索每个可用值(最多INT_MAX)。这最终会导致内存爆炸,这对任何人都不利。

对于初学者来说,本机选项总是比没有问题的脚本更快。最好查看the documentation for what the terms aggregation,因为有很多小边缘情况(例如,shard_size),但也因为两个示例都是terms聚合,所以他们做同样的事情。

不同之处在于,当聚合检查脚本的每个文档时,它需要做更多工作:它需要执行将连接两个值的Groovy脚本,然后返回单个 ,连接值作为所述文档的术语。如果文档碰巧有cityIdcityName的数组,那么非脚本版本实际上最终会识别所有值,而脚本只能识别一个(并且可能无法正常工作) )。

作为旁注,您希望脚本为

"script" : "doc['cityId'].value + doc['cityName'].value"

而不是您作为示例展示的那个,这完全无效。

你可能想要的是:

{
  "size" : 0,
  "aggs": {
    "CityIdCount": {
      "terms": {
        "field": "cityId",
        "size": 0
      },
      "aggs" : {
        "CityNameForId": {
          "terms": {
            "field": "cityName"
          }
        }
      }
    }
  }
}

再一次,没有可怕的"size" : 0。这将为每个cityName提供cityId