ElasticSearch随机分数加上提升?

时间:2017-07-18 10:46:10

标签: elasticsearch random

我正在使用Firebase构建iOS应用,并使用ElasticSearch作为搜索引擎来获取更高级的查询。

我正在尝试实现一个系统,我可以根据查询从索引中获取随机记录。我已经使用" random_score"与种子一起发挥作用。

所以现在所有文件都应该被选中。是否可以添加助推器(抱歉,我是ES新手)?

让我们说文档中有字段" boost_enabled"并且设置为true,文档将被选中的可能性增加3倍,因此"增加"被选为随机的机会?

所以理论上应该是这样的:

与查询匹配的文档:

"document1"
"document2"
"document3"

他们都被选中的机会均等(33%)

我希望实现的目标是" document1"有字段" boost_enabled" = true

它应该是这样的:

"document1"
"document1"
"document1"
"document2"
"document3"

所以现在" document1"被选为随机记录的可能性是其3倍。

真的很感激一些帮助。

编辑:

我想出这样的事情,这是对还是不对?我很确定它不是......

"query" : {
        "function_score": {
            "query": {
                "bool" : {
                    "must": {
                        "match_all": {}
                    },
                    "should": [
                        { "exists" : {
                            "field" : "boost_enabled",
                            "boost" : 3
                            }
                        }
                    ]
                    "filter" : filterArray
                 }
            },

            "functions": [
                {
                    "random_score": {"seed": seed}
                }
            ]
        }
    }

/ Mads

1 个答案:

答案 0 :(得分:1)

是的,Elasticsearch有类似的东西 - 请参阅Elasticsearch: Query-Time Boosting

在你的情况下,你的查询的一部分会记录你所描述的标志的存在,这个“子查询”会有所提升。 bool及其should子句可能会有用。

注意:这并不是说能够说匹配文件的结果可能是n

编辑:

-

编辑1:

Elasticsearch会告诉你如何通过分数得出分数 Explain API可能有助于调整参数。

-

编辑2:

我为上面发布的内容道歉。经过进一步的思考和探索,我认为boost参数不是这里所要求的。 function_score已经有了体重的概念,但即便如此。我发现其他用户的要求与您的要求相似,但看起来没有为此提出任何好的解决方案。

参考文献:

我不认为这些帖子中提出的解决方案是完全正确的。我整理了一个快速shell脚本,命中Elasticsearch REST API并依靠jq(一个流行的CLI来处理JSON)来演示:Github Gist: Flawed Attempt At Weighed Random Sampling with Elasticsearch

在脚本中,featured_flag等同于您的boost_enabledundesired_flag用于演示如何仅考虑索引中的文档子集。您可以复制脚本调整脚本顶部的全局变量,如Elasticsearch服务器,索引等,以试用它。
关于剧本的一些注释:

  • 脚本创建一个启用了featured_flag的文档和一个启用了undesired_flag的文档,该文档不应该被选中
  • TOTAL_DOCUMENTS可用于调整创建的文档总数(包括创建的前两个文档)
  • FEATURED_FLAG_WEIGHT是通过function_score
  • 在查询时应用的权重
  • 脚本重新运行相同的查询1000次,并输出每个创建的文档作为第一个结果返回的次数的统计信息

我认为你的索引中有很多“特色”或“提升”的样本。根据所描述的要求,选择样本的概率取决于文档的权重(假设提升文档为3,其余为1),以及要考虑的所有有效文档的权重总和。因此,似乎简单的权重,提升和随机数不足

很多人在没有Elasticsearch的情况下考虑并发布了加权随机抽样任务的解决方案。这似乎很好地解释了一些方法:electric monk: Weighted Random Distribution。许多算法细节在这里可能不太相关,但我认为它们很有趣。

我认为理想的解决方案需要在Elasticsearch之外完成工作(无需深入研究创建Elasticsearch插件,记分员等)。这是我现在能想到的最好的:

  • 存储在文档中的数字权重字段(可以继续使用布尔字段,但这似乎更灵活)

  • 使用初始查询命中Elasticsearch,利用我们需要的某些统计信息的聚合

    • 可能是文件概率所需权重总和的sum aggregation
    • terms aggregation按重量计算文件的数量(例如m文件的重量为1,n文件的重量为3)
  • 在Elasticsearch之外(在应用程序中),选择示例
    • 生成0到sum_of_weights - 1
    • 范围内的随机数
    • 使用聚合结果和生成的随机数来选择索引(参见Elasticsearch之外的加权随机抽样的算法解决方案),范围为0到total_valid_documents - 1(称为{{1} })
  • 第二次使用适当的过滤器启动Elasticsearch以仅考虑有效文档,selected_index参数保证每次运行此过程时文档集的排序方式相同(可能按权重和文档ID排序) ,sort参数设置为from

与这一切略有关联,我发布了一个略有不同的write up