假设我有以下顺序的Elasticsearch索引:
index-2022-04
index-2022-05
index-2022-06
...
index-2022-04
表示2022年4月存储的数据,index-2022-05
表示2022年5月存储的数据,以此类推。现在,假设在我的查询有效负载中,我有以下时间戳范围:
"range": {
"timestampRange": {
"gte": "2022-04-05T01:00:00.708363",
"lte": "2022-06-06T23:00:00.373772"
}
}
上面的范围说明我想查询从4月5日到5月6日之间存在的数据。这意味着我必须查询三个索引index-2022-04
, index-2022-05
和index-2022-06
中的数据。是否有一种简单有效的方法可以跨这三个索引执行此查询,而不必逐个查询每个索引?
我使用Python来处理查询,我知道我可以同时查询不同的索引(参见这篇文章)。任何提示或指示都将有所帮助,谢谢。
您只需要为索引定义别名,并查询别名而不是索引,让ES确定需要访问哪些底层索引。
最后,为了提高搜索性能,你还可以在timestampRange
上配置索引时间排序,这样,如果你的别名跨越了整整一年的索引,ES就知道根据查询中的范围约束只访问其中的三个。2022-04-05) .
就像你写的,你可以简单地使用通配符和/或传递一个列表作为目标索引。
最简单的方法是用星号通配符(例如index-*
或index-2022-*
)作为目标来查询所有索引。您不需要为它定义别名,只需在目标字符串中使用通配符,如下所示:
from elasticsearch import Elasticsearch
es_client = Elasticsearch('https://elastic.host:9200')
datestring_start = '2022-04-05T01:00:00.708363'
datestring_end = '2022-06-06T23:00:00.373772'
result = es_client.search(
index = 'index-*',
query = { "bool": {
"must": [{
"range": {
"timestampRange": {
"gte": datestring_start,
"lte": datestring_end
}
}
}]
}
})
这将查询匹配模式的所有索引,但我希望Elasticsearch对此执行某种优化。正如@Val在他的回答中所写,配置索引时间排序将有利于性能,因为它限制了当索引排序和搜索排序相同时应该访问的文档数量。
为了完整起见,如果您真的只想将相关的索引名称传递给Elasticsearch,另一种选择是首先在Python端找出您需要查询的索引序列,并将其作为逗号分隔列表(例如['index-2022-04', 'index-2022-05', 'index-2022-06']
)作为目标。例如,您可以使用Pandas date_range()
函数轻松生成这样的索引列表,如
from elasticsearch import Elasticsearch
import pandas as pd
es_client = Elasticsearch('https://elastic.host:9200')
datestring_start = '2022-04-05T01:00:00.708363'
datestring_end = '2022-06-06T23:00:00.373772'
months_list = pd.date_range(pd.to_datetime(datestring_start).to_period('M').to_timestamp(), datestring_end, freq='MS').strftime("index-%Y-%m").tolist()
result = es_client.search(
index = months_list,
query = { "bool": {
"must": [{
"range": {
"timestampRange": {
"gte": datestring_start,
"lte": datestring_end
}
}
}]
}
})