私信  •  关注

Nikolay Vasiliev

Nikolay Vasiliev 最近创建的主题
Nikolay Vasiliev 最近回复了

你所观察到的很可能是 terms 聚合,因为 文档计数是近似值 . 这与 reverse_nested ,也不 nested 聚合。

简言之,由于数据分布在碎片上,ElasticSearch首先在每个碎片上进行本地最佳猜测,然后在碎片上组合结果。为了得到更好更详细的解释,请查看 this section of the documentation .

为了确保事实如此,您可以添加 top_hits 聚合 explain 启用:

      "aggs": {
        "noOfParents": {
          "reverse_nested": {},
          "aggs": {
            "top hits": {
              "top_hits": {
                "size": 10,
                "explain": true
              }
            }
          }
        }
      }

这将为您提供匹配的父文档及其碎片ID的列表。像这样的:

  "aggregations": {
    "mainGrouping": {
      ...
      "groupBy": {
        ...
        "buckets": [
          {
            "key": "1",
            "doc_count": 5,
            "noOfParents": {
              "doc_count": 5,
              "top hits": {
                "hits": {
                  "total": 5,
                  "max_score": 1,
                  "hits": [
                    {
                      "_shard": "[my-index-2018-12][0]", <-- this is the shard
                      "_node": "7JNqOhTtROqzQR9QBUENcg",
                      "_index": "my-index-2018-12",
                      "_type": "doc",
                      "_id": "AWdpyZ4Y3HZjlM-Ibd7O",
                      "_score": 1,
                      "_source": {
                        "parent": "A",
                        "child": {
                          "id": "1"
                        }
                      },
                      "_explanation": ...
                    },

另一种证明这是问题根源的方法是将查询隔离在一个shard中。这样做就足以增加 routing 搜索请求: ?routing=0

这会让你 条款 桶数在一个碎片内稳定。然后比较 noOfParents 与预期数量的父级(同样,在同一个碎片内)。

希望能有帮助!

6 年前
回复了 Nikolay Vasiliev 创建的主题 » 删除未使用的数据ElasticSearch

你可能会面临一些副作用 _forcemerge 在非只读索引上:

警告:只能对只读索引调用强制合并。对读写索引运行强制合并可能会导致生成非常大的段(每个段大于5GB),并且合并策略将永远不会考虑再次合并,除非它主要由已删除的文档组成。这会导致非常大的碎片留在碎片中。

在这种情况下,我建议首先将索引设为只读:

PUT your_index/_settings
{
  "index": {
    "blocks.read_only": true
  }
}

然后,要再次强制合并并启用对索引的回写,请执行以下操作:

PUT your_index/_settings
{
  "index": {
    "blocks.read_only": false
  }
}

如果这不起作用,您可以 reindex 从旧索引到新索引,然后删除旧索引。

有没有更好的删除旧日志的方法?

看起来您想删除旧的日志消息。尽管可以通过查询发出删除,但实际上有一种更好的方法:使用 Rollover API .

其想法是每次旧索引变大时都创建一个新索引。写入将发生在固定的 alias ,当旧索引太旧或太大时,Rollover API将使别名指向新索引。然后,要删除旧数据,只需删除旧索引。

希望有帮助!