【问题标题】:ElasticSearch boost documents score based on results from a query on a different typeElasticSearch 根据不同类型的查询结果提高文档分数
【发布时间】:2014-02-09 02:39:15
【问题描述】:

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

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

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

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

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

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

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

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

更新:

我对大量产品目录和大量销售数据进行了一些测试: 产品(类型)文件数量:500 000 SalesHistory(类型)文档计数: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
    ...
  }
}

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

结论

没有必要以任何其他方式实现这种情况,而不是作为子文档。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      相关资源
      最近更新 更多