在 Elasticsearch 中跨多个索引进行顺序搜索

Sequential Searching Across Multiple Indexes In Elasticsearch

假设我有以下顺序的 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-04index-2022-05index-2022-06 中查询数据。有没有一种简单有效的方法可以跨这三个索引执行此查询,而不必逐个查询每个索引?

我正在使用 Python 来处理查询,并且我知道我可以同时查询不同的索引 ()。任何提示或指示都会有所帮助,谢谢。

您只需要 define an alias 遍历您的索引并查询别名而不是索引,然后让 ES 确定它需要访问哪些基础索引。

最终,为了提高搜索性能,您还可以在 timestampRange 上配置 index-time sorting,这样如果您的别名跨越一整年的索引,ES 只知道访问其中的三个基于查询中的范围限制 (2022-04-05 -> 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 在他的回答中所写,配置 index-time sorting 将有利于性能,因为它限制了当索引排序和搜索排序相同时应访问的文档数量。

为了完整起见,如果您真的只想将相关的索引名称传递给 Elasticsearch,另一种选择是首先在 Python 端确定您需要查询和提供这些索引的索引序列作为 comma-separated 列表(例如 ['index-2022-04', 'index-2022-05', 'index-2022-06'])作为目标。你可以例如 个索引,像这样

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                 
                                 }
                             }
                         }]
                     }
                 })