有没有一种方法可以从 Elasticsearch 索引中获取真正随机的样本?即从索引中检索任何文档的查询,其概率为 1/N
(其中N
是当前索引的文档数)?
作为跟进问题:如果所有文档都具有某些数字字段 s
,是否有一种获取加权随机采样文档的方法,即获取文档 i
的概率与值 s_i
相等,即 s_i / sum(s_j for j in index)
?
有没有一种方法可以从 Elasticsearch 索引中获取真正随机的样本?即从索引中检索任何文档的查询,其概率为 1/N
(其中N
是当前索引的文档数)?
作为跟进问题:如果所有文档都具有某些数字字段 s
,是否有一种获取加权随机采样文档的方法,即获取文档 i
的概率与值 s_i
相等,即 s_i / sum(s_j for j in index)
?
我知道这是一个老问题,但现在可以使用random_score
{
"size": 1,
"query": {
"function_score": {
"functions": [
{
"random_score": {
"seed": "1477072619038"
}
}
]
}
}
}
对我来说,它处理大约200万个文档非常快。
我使用当前时间戳作为种子,但您可以使用任何您喜欢的种子。最好是如果您使用相同的种子,您将获得相同的结果。因此,您可以使用用户会话ID作为种子,所有用户将具有不同的顺序。
在1.3.1版本及以下的Elasticsearch中,我所知道的从索引中获取随机文档的唯一方法是使用脚本:
sort: {
_script: {
script: "Math.random() * 200000",
type: "number",
params: {},
order: "asc"
}
}
function_score
查询时使用random_score。{
"size":1,
"query": {
"function_score": {
"functions": [
{
"random_score": {
"seed": 11
}
}
],
"score_mode": "sum",
}
}
}
不好的一面是这会给每个文档随机打分,然后排序文档并返回第一个。我不知道是否有智能工具可以只选择一个随机文档。
var result = _elastic.Search<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs.Functions(f => f.RandomScore())
.Query(fq => fq.MatchAll()))));
原始查询方式:
GET index-name/_search
"size": 1,
"query": {
"function_score": {
"query" : { "match_all": {} },
"random_score": {}
}
}
}
random_score
来随机排序响应或以约1/N
的概率检索文档。