我了解Elasticsearch聚合查询本质上需要花费很长时间才能执行,尤其是在高基数字段上。在我们的用例中,我们只需要带回按字母顺序排序的前x个存储桶。考虑到我们只需要带回10个存储桶,有没有一种方法可以使我们的查询更快?有没有办法让Elasticsearch只查看每个分片中的前10个存储桶并仅比较它们?

这是我的查询...

{
    "size": "600",
    "timeout": "60s",
    "query": {
        "bool": {
            "must": [
                {
                    "match_all": {
                        "boost": 1
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    },
    "aggregations": {
        "firstname": {
            "terms": {
                "field": "firstname.keyword",
                "size": 10,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": {
                    "_key": "asc"
                },
                "include": ".*.*",
                "exclude": ""
            }
        }
}
}

我想我正在使用复合聚合代替。像这样...
"home_address1": {
    "composite": {
        "size": 10,
        "sources": [
            {
                "home_address1": {
                    "terms": {
                        "field": "home_address1.keyword",
                        "order": "asc"
                    }
                }
            }
        ]
    }
}

在Postman中进行测试表明,该请求的处理速度更快。这是预期的吗?如果是这样,那就太好了。如何将包含,排除属性添加到复合查询中?例如,有时我只想包括值匹配“A. *”的存储桶

如果该查询不应该更快,那么为什么会这样呢?

最佳答案

不幸的是,复合术语aggs不支持includeexclude和许多其他标准术语aggs的参数,因此您有两种选择:

  • 从查询中过滤出与前缀不匹配的文档,例如@Val pointed out

  • 要么
  • 使用脚本为您进行过滤。不过,这应该是您的不得已的办法–与标准查询过滤器相比,脚本可以保证运行得更慢。
  • {
      "size": 0,
      "aggs": {
        "home_address1": {
          "composite": {
            "size": 10,
            "sources": [
              {
                "home_address1": {
                  "terms": {
                    "order": "asc",
                    "script": {
                      "source": """
                        def val = doc['home_address1.keyword'].value;
                        if (val == null) { return null; }
    
                        if (val.indexOf('A.') === 0) {
                          return val;
                        }
    
                        return null;
                      """,
                      "lang": "painless"
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
    

    顺便说一句,您原来的terms agg已经似乎已经优化,所以令惊讶的是composite更快。

    关于performance - 当我只想要前10个存储桶时,是否可以使Elasticsearch聚合更快?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61455802/

    10-14 12:27