弹性搜索受欢迎程度实时得分的替代方案

时间:2015-03-03 01:48:36

标签: elasticsearch

我希望按受欢迎程度提高文档的分数。我希望它尽可能实时。

为了满足实时要求,似乎每次文档的流行度更改时,我都必须重新索引每个文档(每个视图)。这似乎非常低效。

另一种方法是运行一个批处理过程,该过程定期重新索引最近查看过的文档,但这变得不那么实时,并且仍然需要在只有一个字段(流行度)发生变化时重新索引整个文档。

第三种方法(我们已经实现)是使用插件从外部源获取文档的受欢迎程度,并使用脚本将其包含在评分中。这也可以,但会减慢对大型文档空间的搜索速度。使用rescore有帮助,但它只允许我们对返回的文档的子集进行排序。

是否有更好的选择(在不重新索引整个文档的情况下为索引添加流行度的方法或将外部数据与弹性搜索集成的更好方法)?

3 个答案:

答案 0 :(得分:1)

您可以尝试以下方法来获得实时人气字段。

  1. 在您的索引中加入一个人气字段。

  2. 每次检索文档时增加流行度。您可以使用部分更新脚本执行此操作。

  3. 使用功能评分查询来提升文档。
  4. Java API:

    new FunctionScoreQueryBuilder(matchQuery("canonical_name",
                                    phrase).analyzer("standard")
                                    .minimumShouldMatch("100%")).add(
                                    fieldValueFactorFunction("popularityScore")
                                            .modifier(Modifier.LOG1P).factor(2f))
                                    .boostMode("sum"))
    

    http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/boosting-by-popularity.html

答案 1 :(得分:0)

我们实施了第二种和第三种方法的混合体。我们有一个外部源(在我们的例子中是一个数据库),它存储了文档ID的流行度值以及从那里提供的所有关于流行度的查询。另外,我们有一个cron,通过重新索引每小时更新所有文档。我们重新编制索引的原因是因为我们对需要新流行度的文档进行了其他分析,但从技术上讲,您只能拥有数据库,因为它满足所有请求目的。

对于doc id的数字检索而言,DB的速度通常比eelstic search / lucene / solr快得多。希望这会有所帮助。

答案 2 :(得分:0)

我知道这是一个老问题,但是Elasticsearch发布了一项实验性功能,您可以在搜索查询中为每个文档提供排名: https://www.elastic.co/blog/made-to-measure-how-to-use-the-ranking-evaluation-api-in-elasticsearch

基本上,如果您认为某些搜索查询会返回某些文档,则可以在搜索查询中提供这些文档(其ID)以及排名(每个文档)。如果提供的文档ID在搜索结果中,则其排名将用于提升自身。

由于您必须在搜索查询中提供一组文档ID及其等级,因此您需要某种方式(事先)确定搜索结果中是否应包含这些文档。

此功能乍一看似乎是错误的方法,因为您需要在执行实际搜索之前先找出潜在的结果。但是也许是这样。至少是实时的。

https://www.elastic.co/guide/en/elasticsearch/reference/6.7/search-rank-eval.html