ElasticSearch 中的随机文档

Posted

技术标签:

【中文标题】ElasticSearch 中的随机文档【英文标题】:Random document in ElasticSearch 【发布时间】:2014-11-11 07:54:03 【问题描述】:

有没有办法从弹性搜索索引中获取真正随机的样本?即从索引中检索任何文档的查询概率为1/N(其中N 是当前索引的文档数)?

作为后续问题:如果所有文档都有一些数字字段s,有没有办法通过加权随机抽样来获取文档,即获取文档i 的概率为s_i等于s_i / sum(s_j for j in index)?

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,但现在可以使用random_score, 使用以下搜索查询:


   "size": 1,
   "query": 
      "function_score": 
         "functions": [
            
               "random_score": 
                  "seed": "1477072619038"
               
            
         ]
      
   

对我来说,大约 200 万份文档非常快。

我使用当前时间戳作为种子,但你可以使用任何你喜欢的东西。最好的是,如果您使用相同的种子,您将获得相同的结果。因此,您可以使用用户的会话 ID 作为种子,所有用户的顺序都不同。

【讨论】:

对于较新版本的 ES:elastic.co/guide/en/elasticsearch/reference/5.4/…【参考方案2】:

我知道从索引中获取随机文档的唯一方法(至少在版本

sort: 
  _script: 
    script: "Math.random() * 200000",
    type: "number",
    params: ,
    order: "asc"
 

您可以使用该脚本根据记录的某些字段进行加权。

将来他们可能会添加更复杂的东西,但您可能必须向 ES 团队提出要求。

【讨论】:

不能使用种子。 n 个文档将被分组并具有相同的分数,其中 n 是分片大小。 无痛脚本 Math.random() 是否返回介于 0 和 1 之间的值?【参考方案3】:

您可以将 random_score 与 function_score 查询一起使用。


    "size":1,
    "query": 
        "function_score": 
            "functions": [
                
                    "random_score":  
                        "seed": 11
                    
                
            ],
            "score_mode": "sum",
        
    

不好的部分是这将对每个文档应用随机分数,对文档进行排序,然后返回第一个。我不知道有什么聪明的东西可以随机选择一个文档。

【讨论】:

【参考方案4】:

您可以使用random_score 随机排序响应或检索具有大致1/N 概率的文档。

补充说明:

https://github.com/elastic/elasticsearch/issues/1170 https://github.com/elastic/elasticsearch/issues/7783

【讨论】:

【参考方案5】:

NEST 方式:

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": 
        
    

【讨论】:

以上是关于ElasticSearch 中的随机文档的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:使用新的 field API 简化 Painless 语法和文档字段访问 - Elastic Stack 8.1

Elasticsearch:使用新的 field API 简化 Painless 语法和文档字段访问 - Elastic Stack 8.1

Elastic:使用 Python 方便地实现 Elasticsearch-To-CSV 导出

Elastic Search 基本操作

Elasticsearch:从 Elastic Stack 中的时间戳谈开去

ElasticSearch快速入门