我在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
搜索孩子的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
上与条目“*”匹配,并且在所提供的两个日期之间有子项。因为我只关心聚合,所以我不会返回任何文档,我只需要匹配一个子文档。
如何提高查询速度?
答案 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
所以我想,您必须删除这些参数才能加快查询速度。