【问题标题】:restructure elasticsearch index to allow filtering on sum of values重构弹性搜索索引以允许过滤值的总和
【发布时间】:2020-05-31 07:28:48
【问题描述】:

我有一个产品索引。

每个产品都有多个变体(可以是几个或数百个,每个都有颜色和尺寸,例如红色)

每个变体都可以(以一定数量)在多个仓库(大约 100 个仓库)提供。

仓库有代码,例如AB、XY、CD等

如果我可以选择,我会将其编入索引:

stock: {
  Red: {
    S: { AB: 100, XY: 200, CD: 20 },
    M: { AB: 0, XY: 500, CD: 20 },
    2XL: { AB: 5, XY: 0, CD: 9 }
  },
  Blue: { 
    ...
  }
}

这是我可能会收到的一种客户查询:

向我展示所有在 AB 和 XY 仓库的库存中有 Red.S 颜色的产品(最少 100 件)。

所以这可能是一个类似的过滤器

Red.S.AB > 100 AND Red.S.XY > 100

我没有在这里写完整的filter 查询,但它在弹性中很简单。

我们也可能得到 SUM 查询,例如AB 和 XY 的库存总和应该 > 500。

这很容易通过脚本过滤器,比如Red.S.AB + Red.S.XY > 500

问题是,给定 100 个仓库、100 种尺寸、25 种颜色,这很容易需要 100*100*25 = 250k 个映射。 Elasticsearch 根本无法处理那么多键。

简单的答案是使用嵌套文档,但是嵌套文档会带来一个特殊的问题。我们无法对给定的嵌套文档选择求和,而且嵌套文档很慢,特别是当我们每个产品要拥有 250k 时。

我也愿意接受外部解决方案而不是弹性解决方案。我们是 rails/postgres 堆栈。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您的产品索引包含变体,这很好,但我会使用另一个索引来管理与多仓库库存相关的任何内容。每个产品/尺寸/颜色/仓库一份文件,带有相关计数。例如:

    {
      "product": 123,
      "color": "Red",
      "size": "S",
      "warehouse": "AB",
      "quantity": 100
    }
    
    {
      "product": 123,
      "color": "Red",
      "size": "S",
      "warehouse": "XY",
      "quantity": 200
    }
    
    {
      "product": 123,
      "color": "Red",
      "size": "S",
      "warehouse": "CD",
      "quantity": 20
    }
    etc...
    

    这样,您的股票查询将更加灵活,因为您只需过滤字段(productcolorsizewarehouse)并简单地聚合在 quantity 字段上,总和、平均值或您可能想到的任何内容。

    您可能需要利用bucket_script pipeline aggregation 来确定总和是否高于或低于所需阈值。

    与每次商品缺货时都必须更新主产品文档相比,通过简单地为任何给定组合索引新数量来维护库存变动也容易得多。

    无需脚本,无需嵌套文档。

    【讨论】:

    • 单独索引意味着我总是执行 2 个查询?因为用户也可能在搜索产品数据,所以我需要先执行库存查询,找出匹配产品的 id(可能有数千个),然后将这些 id 作为第二次查询产品索引的输入?例如,找到 id 是这数千个 id 之一,name 就像“软衬衫”
    • 是的,除非您决定将更多产品字段添加到您也可以搜索的库存文档中。
    【解决方案2】:

    最好的解决方案是为仓库创建单独的索引,每个仓库索引都有文档。每个产品/尺寸/颜色/仓库一份文件,相关值如下:

    {
      "product": 123,
      "color": "Red",
      "size": "S",
      "warehouse": "AB",
      "quantity": 100
    }
    

    这将减少每个索引 100 * 25 = 2500 个映射。

    休息其他操作,我觉得@Val在他的回答中提到了非常令人印象深刻和美丽的。

    谈到外部解决方案,我想说您要执行存储数据、搜索和获取数据的任务。 Elasticsearch 和 Apache Solr 是执行此类任务的最佳搜索引擎。我没有尝试过 Apache Solr,但我强烈建议使用 Elasticsearch,因为它的功能、积极的社区支持和搜索速度非常快。使用分析器和标记器也可以快速进行搜索。它还具有全文搜索和术语级别搜索等功能,可根据情况或问题陈述自定义搜索。

    【讨论】:

    • 为什么要为每个仓库单独索引?仓库是一个字段,因此所有文档都可以进入一个索引,只有几个字段......
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2015-11-20
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    相关资源
    最近更新 更多