我正在开发一个 Python 程序,它可以为我提供给定 Elastic Search 索引中所有文档的统计信息。我们索引中的文档有许多未在 ES 设置中专门映射的字段。它们只是被视为不透明的文本字符串(我们不会通过它们进行搜索或聚合)。
简而言之,这就是脚本的作用
它下载给定索引中的每个文档(match_all,没有任何选择器)
它保留在任何文档中至少出现一次的所有字段的列表,以点表示法:
FirstLevel.SecondLevelArray[..].ThirdLevel
对于每个字段,它会计算有多少文档拥有该字段
对于每个字段,它列出了该字段在所有文档中具有的前 100 个值(包括该值在所有文档中该字段中出现的频率)
示例输出:
FirstLevel.SecondLevelArray[].ThirdLevel appears 9423 times. Top values: 1010 times Value1, 900 times Value2, 423 times Value3
这是一个非常方便的工具,可以让我们审核索引中的文档。
当然,从索引中获取所有文档然后进行这些计数可能非常耗时。所以我想知道:
ES 中是否有内置功能可以为我提供此类统计数据,而无需我自己执行此操作?
如果没有,有没有办法获取 N 个文档的随机“样本”,而不是调用“match_all”来下载所有文档,例如只返回每 10 个或 100 个文档?
这是我现在运行的代码片段,获取两个日期之间的所有文档:
from elasticsearch import Elasticsearch client = Elasticsearch("https://localhost:9200/")
QUERY_RANGE = { "range": { INDEX_FIELD_TIME: { "gte": DATE_START, "lte": DATE_END } } }
QUERY_RANGE_SORT = [ { INDEX_FIELD_TIME: "asc" }, { INDEX_FIELD_ID: "asc" } ]
while True:
resp = client.search(index=INDEX_NAME, query=QUERY_RANGE, size=5000, sort=QUERY_RANGE_SORT, search_after=[ 0, 0 ])
# Write resp to file
if len(resp['hits']['hits']) == 0:
break
我该如何更改,以便我只获得文档样本(例如每 10 个或 100 个)?
我通读了random_sampler聚合,但这依赖于某些字段的聚合,这是我不想要的。我想要整个文档的样本集。
我认为您可以尝试 field_stats 查询,但这不能应用于文本字段。示例查询将类似于 ..
GET index_name/_search
{
"size": 0,
"aggs": {
"field_stats": {
"stats": {
"field": "your_field_name"
}
}
}
}
我希望这至少能帮助您满足您的一些要求