【问题标题】:Sorting by product price considering special prices (client, group, country)考虑特殊价格(客户、团体、国家)按产品价格排序
【发布时间】:2019-09-12 09:11:26
【问题描述】:

我们的商店有一些产品(约 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 这样的东西会是一种选择?

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

最好的问候

【问题讨论】:

    标签: elasticsearch elasticsearch-painless


    【解决方案1】:

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

    考虑到您只有 5000 个文档,使用script 进行排序的想法很好。脚本性能不佳,但在您的情况下,这可能无关紧要。

    总的来说,这看起来很棘手,因为您需要在产品和价格之间进行某种连接,而 Elasticsearch 并不擅长连接。它有 some joining options: nested 数据类型、join 数据类型(又名父子)和非规范化。您已经考虑的最后一个 - 当您在原始产品文档中输入不同的价格时。

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

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多