ElasticSearch 根据不同类型的查询结果提高文档得分

标签 elasticsearch

我正在制作基于 ElasticSearch 的电子商务产品目录的原型(prototype)。 每个产品都被索引为一个文档(其中包含名称和描述等属性)。

有一件事我无法解决,我想根据用户的购买历史提高某些产品的分数。

我能想到的唯一选择是将购买历史存储为产品的子文档。然后将 custom_filters_score 与过滤器一起使用,以查找具有给定 userId 的子文档。在这种情况下,过滤器确定给定产品是否已被给定用户购买,如果是,它将提高分数。

这种方法的问题是某些产品可能每月被购买数十万次,我不确定 ElasticSearch 在这种情况下的表现如何。

完美的解决方案是,如果我可以将购买历史记录放在单独的索引中,或者放在同一索引中但作为不同的文档类型(比如说“userspurchasehistory”)。示例文档:

{userId: 1234, purchesedProducts: [34,112323,1223,32342,31234]}

然后使用查询分数提升,它表示如下:如果术语 34 (productId) 出现在 userspurchasehistory(类型)文档的“purchesedProducts”(字段名称)中,其“userId”等于 1234,则将查询提升因子 2。

这里有什么想法或想法吗?

更新:

我对大量产品目录和大量销售数据进行了一些测试: 产品(类型)文档数:500 000 销售历史(类型)文档数:14 000 000 索引大小:2.5GB Elastic Serach:一个节点,所有默认设置

SalesHistory 文档是产品文档的子文档。 销售条目分布:

~20% of products: 40 entries 
~20% of products: 30 entries 
~20% of products: 20 entries 
~20% of products: 10 entries 
~20% of products: 5 entries 

200 products with 10 000 sales entries (plus previously added 5-40 entries)
200 products with  5 000 sales entries (plus previously added 5-40 entries)
200 products with  2 500 sales entries (plus previously added 5-40 entries)
200 products with  1 000 sales entries (plus previously added 5-40 entries)
200 products with    500 sales entries (plus previously added 5-40 entries)
1 product 18 500 entries

示例查询:

curl -XGET "http://localhost:9200/demoproducts/_search" -d'
{
   "query": {
      "custom_filters_score": {
         "query": {
            "match_all": {}
         }
      },
      "filters": [
         {
            "filter": {
               "has_child": {
                  "type": "saleshistory",
                  "query": {
                     "term": {
                        "userId": {
                           "value": "28875"
                        }
                     }
                  }
               }
            },
            "boost": 2
         }
      ]
   }
}'

结果:

{
  "took": 33,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 500001,
    "max_score": 2
    ...
  }
}

当我向查询添加一些过滤器时(几乎在所有情况下,我们的查询都包含一些过滤器)响应时间约为 7 毫秒

结论

没有必要以任何其他方式将这种情况作为子文档来实现。

最佳答案

无需修改文档,您可以动态构建一个包含用户购买历史记录的条款查询。

curl -XGET "http://localhost:9200/demoproducts/_search" -d'
    {
       "query": {
           "terms": {"id":["34","112323","1223","32342","31234"]}
        }
    }
}

关于ElasticSearch 根据不同类型的查询结果提高文档得分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21225323/

相关文章:

mongodb - 将 MongoDB 与 ElasticSearch 同步

elasticsearch - 如何通过Edgengram匹配百分比对搜索结果进行排名

mysql - 连接来自 Elastic Search 和 MySQL 的数据进行分页的最佳方式是什么?

java - 错误: `elasticsearch` directory is missing in the plugin zip

elasticsearch - 在 Kibana 中搜索字符串

lucene - 在 ElasticSearch 中使用突出显示 _source :false

elasticsearch - 如何在ElasticSearch Head Chrome扩展程序中运行术语查询?

spring-boot - java.lang.RuntimeException:使用本地的Spring Boot容器api时连接被拒绝

elasticsearch - Elasticsearch中的总结

amazon-web-services - Filebeat 和 AWS Elasticsearch - 不工作