【问题标题】:ElasticSearch random score combined with boost?ElasticSearch 随机分数与提升相结合?
【发布时间】:2017-12-23 04:35:05
【问题描述】:

我正在使用 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}
                }
            ]
        }
    }

/疯子

【问题讨论】:

    标签: elasticsearch random


    【解决方案1】:

    在 ES 7.15 中我使用 {script_score} 键,您可以在下面看到我的示例。

    此代码 "source": "_score + Math.random()" 将随机 0.0 -> 1.1 数字添加到我的原生提升分数中。想了解更多可以see this

    {
        "size": { YOUR_SIZE_LIMIT },
        "query": {
            "script_score": {
                "query": {
                    "query_string": {
                        "fields": [
                            "{ YOUR_FIELD_1 }^6",
                            "{ YOUR_FIELD_2 }^3",
                        ],
                        "query": "{ YOUR_SEARCH_QUERY }"
                    }
                },
                "script": {
                    "source": "_score + Math.random()"
                }
            }
        }
    }
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案2】:

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

    在您的情况下,您将有一部分查询记录您描述的标志的存在,并且此“子查询”会有所提升。 bool 及其 should 子句可能会很有用。

    注意:这并不完全像能够说匹配文档是 n 次一样可能是结果

    编辑:

    --

    编辑 1:

    Elasticsearch 将通过 Explain API 这可能有助于调整参数。

    --

    编辑 2:

    对于我在上面发布的内容,我深表歉意。经过进一步的思考和探索,我认为boost 参数并不是这里所需要的。 function_score 已经有了重量的概念,但即使这样也不够。我发现其他用户的要求与您的相似,但似乎没有为此提出任何好的解决方案。

    参考资料:

    我认为这些帖子中提出的解决方案并不完全正确。我编写了一个快速的 shell 脚本来访问 Elasticsearch REST API 并依靠 jq(一种流行的处理 JSON 的 CLI)来演示: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范围内的随机数
      • 使用聚合结果和生成的随机数来选择一个范围在 0 到 total_valid_documents-1 之间的索引(请参阅 Elasticsearch 之外的加权随机抽样的算法解决方案)(称为 selected_index)李>
    • 使用适当的过滤器再次点击 Elasticsearch 以仅考虑有效文档,sort 参数可确保每次运行此过程时文档集的排序方式相同(可能按权重和文档 ID 排序),并且将from 参数设置为selected_index

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

    【讨论】:

    • 但是,它会给我类似的效果,还是完全不现实?
    • 我认为您必须进行试验,看看它是否有效。我认为它应该通过为随机和正确的提升选择正确的权重来解决。如果您还没有找到,请查看“解释”功能/Elasticsearch 对分配的分数的解释,以帮助您。
    • 非常感谢您的帮助。我已将查询添加到帖子中,我应该这样做吗?
    • 这与我的想法很相似。我认为在使用 Explain API 时您可能想要尝试的另一件事是 random_scoreweightboost_modescore_mode 的组合如何协同工作。仔细查看 function_score 文档,可能有一条可能的路线没有查询提升,没有核心 Elasticsearch 相似性评分,只有 function_score 评分。我会尝试用更多细节来更新我的答案。
    • 嘿,谢谢! - 我指定的查询的当前问题是,如果该字段不存在于任何文档中,则查询不会返回任何文档。我仍然希望能够拥有其他文档,只是给具有该字段的文档更高的被选中“机会”。您能否尝试将我的查询编辑为您认为它应该是的样子? - 所有其他过滤器和查询应该匹配。该应用程序向用户显示其他用户发布的随机文档。如果用户对该文档应用了提升,它应该被“提升”,更多的人会更快地看到它。所以优先考虑
    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    相关资源
    最近更新 更多