当前位置: 首页 > 知识库问答 >
问题:

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

戈念
2023-03-14

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

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

我能想到的唯一选择是将购买历史记录存储为产品的子文档。然后使用custom\u filters\u score和过滤器,该过滤器查找具有给定用户ID的子文档。在这种情况下,过滤器确定给定的产品是否已被给定的用户购买,如果是,它将提高分数。

这种方法的问题是,一些产品可能每月被购买数十万次,我不确定弹性搜索在这种情况下会如何运行。

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

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

然后使用查询分数提升,表达如下内容:如果术语34(productId)出现在用户历史记录(类型)文档的“用户ID”等于1234的“购买产品”(字段名)中,则按因子2提升查询。

有什么想法吗?

更新:

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

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

~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

结论

没有必要将此案例作为子文档以任何其他方式实现。

共有1个答案

郗浩言
2023-03-14

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

curl -XGET "http://localhost:9200/demoproducts/_search" -d'
    {
       "query": {
           "terms": {"id":["34","112323","1223","32342","31234"]}
        }
    }
}
 类似资料:
  • 我在ElasticSearch有索引。其中的文档具有重复的字段值。在查询结果中,我需要删除所有重复项,并且只获得不同的值。例如: PUT localhost:9200/人 POST localhost:9200/人/人 我试图通过字段“name”删除重复的术语聚合,但它不起作用。 获取localhost:9200/person/person/_search 结果: 聚合应用于name=“marry

  • 我有一个索引(名称:“index1”)指向ElasticSearch中的多个文档。 文档的格式(json)是- 下面是映射- 我在ES查询中哪里做错了?

  • elasticsearch实例的一些背景: 一个节点,在一台机器上 特定索引由大小为1.23TB的26亿文档组成 索引被分成4个碎片。 堆大小设置为30 GB 服务器有256GB内存和40个内核。 Elasticsearch(版本1.4.3)是这个服务器上唯一运行的东西 我想返回所有具有特定名称的文档。属性名称已映射为: 我尝试过使用不同类型的搜索;过滤器、查询字符串、术语。结果都一样。当前查询如

  • 我在Elasticsearch版本1.3.4中有以下查询: 映射如下所示: 最后,对于技能(不包括其他部分),文档结构如下所示: 我使用这个查询的目标是,首先用过滤器过滤掉一些不相关的点击(查询的底部),然后通过搜索整个文档中的match\u短语“java”来给一个人打分,如果它还包含match\u短语“adobe creative suit”,则会额外提高分数,然后检查在“skills”中点击的

  • 我试图通过根据场值提升_score来摆脱弹性搜索中的排序。这是我的场景: 我的文档中有一个字段:应用日期。这是自EPOC以来经过的时间。我希望具有更大应用日期(最近)的记录具有更高的分数。 如果两个文档的分数相同,我想在另一个字符串类型的字段上对它们进行排序。说“状态”是另一个可以有值的字段(可用、进行中、关闭)。所以,具有相同应用程序日期的文档应该根据状态_score。可用应该有更多的分数,进行

  • 问题内容: 我正在尝试在Elasticsearch上运行看起来像一个简单查询的内容,但似乎无法获得想要的结果。 这是我要做的简短示例: 我有一个新闻数据库。每条新闻都包含一个来源,一个标题,一个时间戳和一个用户。 我想要获得给定用户的每个可用来源的最新标题(基于时间戳)。 那么,例如,如何从约翰那里获得最后的CNN和最后的ESPN头条新闻? 我一直在研究多重搜索API,但这意味着我需要事先了解所有