【问题标题】:elasticsearch parent child extremely inefficient has_child queryelasticsearch父子效率极低的has_child查询
【发布时间】:2016-07-07 07:49:10
【问题描述】:

我在 ES 索引中有父子关系。就文档数量而言,父母(200M 文档)和 80% 孩子(1B 文档)的文档数量分布约为 20%。 ES 集群有 5 个节点,每个节点有 20GB RAM 和 4 个 CPU 内核。 ES 版本是 1.5.2。我们每个索引使用 5 个分片和 0 个复制。

当我使用has_child 查询它时,处理速度非常慢 - 170 秒。然而,当我只是跑过父母时,不到一秒钟。

此查询需要很长时间才能返回并导致应用程序超时。我真的很关心聚合和时间范围过滤器。

我相信正在发生的事情是查询首先在每个孩子身上运行以进行过滤。实际上,我只希望它先运行父母并检查是否有单个文档,然后对孩子使用过滤器。

设置

_parent 是一个看起来像这样的操作

{
     "a": "m_field",
     "b": "b_field",
     "c": "c_field",
     "d": "d_field"
}

_child 是该操作发生时的时间戳

{
     "date": "2016-07-07T11:11:11Z"
}

这些通常存储在时间序列索引中。索引按月分片。一个索引通常在磁盘上占用大约 70GB 的总大小。我们选择通过别名运行它,该别名结合了所有或部分最新索引。

查询

当我查询时,我在 _parent 文档上执行 query_string 以搜索 keyword 和子级上的 Range 过滤器,使用 has_child 查询。

如下所示。

{
  "size": 0,
  "aggs": { 
     "base_aggs": {
        "cardinality": {
           "field": "a"
        }
      }
  },
  "query": {
     "bool": {
       "must": [
       {
          "filtered": {
             "query": {
                "query_string": {
                    "query": "*",
                    "fields": [
                       "a",
                       "b",
                       "c",
                       "d",
                       "e"
                    ],
                    "default_operator": "and",
                    "allow_leading_wildcard": true,
                    "lowercase_expanded_terms": true
                 }
              },
              "filter": {
                 "has_child": {
                    "type": "evt",
                    "min_children": 1,
                    "max_children": 1,
                    "filter": {
                       "range": {
                          "date": {
                             "lte": "2016-07-06T23:59:59.000",
                             "gte": "2016-06-07T00:00:00.000"
                          }
                       }
                    }
                 }
              }
            }
          }
        ],
        "must_not": [
          {
             "term": {
                "b": {
                   "value": ""
                }
             }
          },
          {
             "term": {
                "b": {
                  "value": "__"
             }
          }
        }
      ] 
    }
  }
}

所以查询应该在我的query_string 上与条目“*”匹配,并且有两个提供的日期之间的孩子。因为我只关心聚合我不返回任何文档,我只需要匹配单个子文档。

问题

如何提高查询速度?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    has_child 查询或过滤器与min_children 的性能 或max_children 参数与has_child 查询非常相似 已启用评分。

    https://www.elastic.co/guide/en/elasticsearch/guide/2.x/has-child.html#min-max-children

    所以我想,您必须删除这些参数以加快查询速度。

    【讨论】:

    • 不幸的是,删除最小/最大子参数并不能加快速度。我假设我可以设置它,以便如果有 1 个或多个匹配的子文档可以包含在聚合中。但无论是否包含它,它仍然表现出相同的行为。
    • 您可以尝试将 evt 范围“过滤器”更改为“查询”范围吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多