按产品价格排序,同时考虑特殊价格(客户,组,国家/地区)

时间:2019-09-12 09:11:26

标签: elasticsearch elasticsearch-painless

我们的商店里有一些商品(〜5000)。 当然,还有类别概述网站,其中显示了当前类别中的所有产品。要求所有产品都可以按价格(ASC和DESC)排序。

这已经(部分地)起作用了,因为问题是,在我们的Elasticsearch中,我们目前只有“原始”价格,因此没有考虑任何产品折扣,因此排序无法正常进行。

我的任务是立即解决该问题。 但是我已经在为“如何”将“特殊价格”坚持到Elasticsearch而苦苦挣扎。

问题在于,通常可以在客户级别,客户群级别和国家/地区对每种产品打折。

所以我想象这样的结构将是一个开始:

# current
{
  "articleNumber": "12345",
  ...
  "price": 9.99,
  ...
}

# new
{
  "articleNumber": "12345",
  ...
  "price": 9.99,
  ...
  "special_prices": [
    {
      "customer": "123456",
      "client_price": 5.99,
      "client_group_price": null,
      "country_de": null
      "country_es": null,
      ...
    },
    ...
  ]
}

以下想法:

  • 特惠价格可以作为嵌套对象存储在产品索引中(但我不确定以后如何对其进行排序)
  • 也许我可以用价格创建第二个索引,然后我将有两个查询,但是我想那可以吗?因为我必须与我们拥有的每个客户(也有大约5000个),每个产品以每个可能的价格建立一个完整的矩阵。但是,如果我有第二个索引,那么我将必须加入,并且排序可能不正确,然后
  • 如果可能的话,我只想保留价格特殊的任何价格,否则,我不想破坏指数

我尝试使用painless进行某种操作以返回特殊价格(如果该价格适用于该产品和客户),但这给了我:

...
"script": "if (doc['special_prices.customer'] != null && doc['special_prices.customer'].value == '123456') { return 12.45; } else { return doc['price']; }",
          "lang": "painless",
          "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [special_prices.customer] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
...

也许像SQL ORDER BY CASE WHEN这样的选项是可行的?

关于我应该如何模拟和坚持特价的任何想法?我如何实现排序? 加入第二个索引是个好主意吗?

最诚挚的问候

1 个答案:

答案 0 :(得分:0)

您看到的错误是因为special_prices.customer没有被索引为keyword,而是一个text(允许全文搜索)。如果您未明确指定映射,Elasticsearch很可能会为您创建一个keyword。只需尝试在脚本中将special_prices.customer替换为special_prices.customer.keyword

考虑到您只有5000个文档,使用script进行排序的想法很好。脚本的性能不佳,但是对于您而言,这可能并不重要。

通常,这看起来很困难,因为您需要在产品和价格之间进行某种联接,而Elasticsearch并不擅长联接。它具有some joining optionsnested数据类型,join数据类型(又称父子)和反规范化。您已经考虑的最后一个-在原始产品文档中输入不同的价格。

不幸的是,我不能推荐一个,因为没有单一的食谱。我会尝试使用脚本,如果性能不够好,请考虑对数据进行重塑。

希望有帮助!