elasticsearch父子极其低效has_child查询

时间:2016-07-07 07:49:10

标签: elasticsearch

我在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。我们选择在别名上运行它,该别名结合了所有或部分最新的索引。

查询

当我查询时,我在query_string文档上执行_parent,以使用keyword搜索孩子的Rangehas_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上与条目“*”匹配,并且在所提供的两个日期之间有子项。因为我只关心聚合,所以我不会返回任何文档,我只需要匹配一个子文档。

问题

如何提高查询速度?

1 个答案:

答案 0 :(得分:0)

  

使用has_child的{​​{1}}查询或过滤器的效果   或min_children参数与max_children查询非常相同   得分已启用。

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

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