【问题标题】:Elastic Search - Sorting & Filtering on nested Documents弹性搜索 - 对嵌套文档进行排序和过滤
【发布时间】:2021-11-19 02:05:45
【问题描述】:

我正在开发一个电子商务应用程序。目录数据由 Elastic Search 提供。 我有已在 Elastic Search 中编入索引的 Product 文档。

文档看起来像这样(为了更好的可读性,排除了几个字段):

{
     "title" : "Product Name",
      "volume" : "200gm",
      "brand" : {
        "brand_code" : XXXX,
        "brand_name" : "Brand Name"
      },
      "@timestamp" : "2021-08-26T08:08:11.319Z",
      "store" : [
        {
          "physical_unit" : 0,
          "default_price" : 115.0,
          "_id" : "1234_111",
          "product_code" : "1234",
          "warehouse_code" : 111,
          "available_unit" : 100
        }
      ],
      "category" : {
        "category_code" : 987,
        "category_name" : "CategoryName",
        "category_url_link" : "CategoryName",
        "super_category_name" : "SuperCategoryName",
        "parent_category_name" : "ParentCategoryName"
      }
    }

上述文档中的 store 对象是 ES Query 查找价格并确定商品是否有货或缺货的对象。

我想添加更多子对象来存储(基本上来自多个库存的数据)。每个产品最多可以有 150 多个子对象。

最终,产品文档将看起来像这样,多个库存数据映射到特定文档。

{
     "title" : "Product Name",
      "volume" : "200gm",
      "brand" : {
        "brand_code" : XXXX,
        "brand_name" : "Brand Name"
      },
      "@timestamp" : "2021-08-26T08:08:11.319Z",
      "store" : [
        {
          "physical_unit" : 0,
          "default_price" : 115.0,
          "_id" : "1234_111",
          "product_code" : "1234",
          "warehouse_code" : 111,
          "available_unit" : 100
        },
        {
          "physical_unit" : 0,
          "default_price" : 125.0,
          "_id" : "1234_112",
          "product_code" : "1234",
          "warehouse_code" : 112,
          "available_unit" : 100
        },
        {
          "physical_unit" : 0,
          "default_price" : 105.0,
          "_id" : "1234_113",
          "product_code" : "1234",
          "warehouse_code" : 113,
          "available_unit" : 100
        }
        Upto N no of stores
      ],
      "category" : {
        "category_code" : 987,
        "category_name" : "CategoryName",
        "category_url_link" : "CategoryName",
        "super_category_name" : "SuperCategoryName",
        "parent_category_name" : "ParentCategoryName"
      }
    }

功能要求:

  1. 对于任何产品,我们应该显示所有仓库的最低价格。 对于 EX:如果特定产品有 50 个商店映射到它,则 Elastic Search 查询应该查看嵌套对象并获取所有 50 个商店中最低的值(如果项目可用)。
  2. 性能不应降低。

挑战:

  1. 如果我们开始为每个产品存储这么多商店,数据将会相当高。这会是个问题吗?
  2. 从嵌套文档中提取最低价格的有效方法是什么?
  3. 构面如何在嵌套文档中工作?就像我应用价格范围过滤器 ES 拾取之前未显示的数据一样。 (它可能会从其他商店中挑选与范围匹配的数据)

我们使用模板查询ES,Elastic Search的版本是6.0。 提前致谢!!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    首先在 7.x 版本中对嵌套文档搜索进行了改进,值得升级。

    至于 6.x 版本,有很多因素我无法给你一个具体的答案。似乎您可能不了解嵌套文档的工作方式,它们不是关系型的。

    特别是当您说每个产品可能有 50 个商店映射到它时,这听起来像是在暗示一种关系,这种关系不会存在于嵌套文档中。但是,来自这 50 个存储的值将存储在嵌套在父文档下的索引中。在一个产品或类别下拥有 50 家商店听起来并不重要。

    自从引入聚合框架以来,ElasticSearch 并没有真正谈论过方面。不是它们不存在,只是不是它们是如何被讨论的。

    所以让我们试试这个。 ElasticSearch 通过分而治之的机制优化其搜索和查询。数据分布在几个分片中,一个可配置的数字,每个分片负责审查自己的数据。此外,这些分片可以分布在多台机器上,以便有许多 CPU 和大量内存用于搜索。因此,如果您愿意扩大集群,那么增加数据并不重要,因为可以维持每台机器执行与以前相同的工作量的情况。

    与关系数据库不同,过滤器搜索词允许 Elastic 大幅减少它正在查看的数据,并且在关系数据库性能下降的情况下,更多的过滤器将提高性能。

    现在回到嵌套文档。它们存储为单独的索引,但不是将结果映射到嵌套文档,而是将结果映射到父文档 ID。因此,您嵌套的文档与文档的其余部分并不完全相同,尽管它们也不是真正分开的。但这确实意味着嵌套文档应该对父文档的查询性能影响最小。但是,如果您的数据大小超出当前系统的容量,您仍然需要增加其大小。

    至于如何查询,您将使用 Elastic 聚合。这些将允许您计算您的“方面”计数并确定最佳价格。 Elastic 聚合非常强大且速度非常快。有一些有据可查的注意事项,但通常它们会按您的预期工作。

    在 6.x 版本中,查询字符串查询无法访问嵌套文档中的搜索条件,必须使用复杂查询。

    回顾

    功能要求:

    1. 对于任何产品,我们应该显示所有仓库的最低价格。 对于 EX:如果一个特定的产品有 50 个商店映射到它, ElasticSearch 查询应该查看嵌套对象并获取 如果有货,价值是所有 50 家商店中最低的。

    是的,嵌套聚合可以做到这一点。

    1. 性能不应降低。

    性能将继续取决于数据大小与整体集群大小的比率。

    挑战:

    如果我们开始为每种产品存储这么多商店,数据将会相当高。这会是个问题吗?

    不,这应该不是问题

    从嵌套文档中提取最低价格的有效方法是什么?

    弹性聚合

    方面如何在嵌套文档中工作?就像我应用价格范围过滤器 ES 拾取之前未显示的数据一样。 (它可能会从其他商店中挑选与范围匹配的数据)

    是的,过滤可以很好地与聚合一起使用。聚合将基于过滤的数据。实际上,您可以仅基于最低价格进行聚合,然后在同一个查询中使用您的价格范围进行聚合,这将为您提供在该价格范围内具有商店的文档的数量,并且您可以有一个子聚合显示每个价格范围内的商店。

    我们使用模板查询ES,Elastic Search的版本是6.0。提前致谢!!

    我对模板一无所知。 ElasticSearch API 非常简单,我不知道为什么有人在 API 之上使用其他工具,它们只是增加了权重,增加了复杂性,并使关键功能不可用,因为包装器作者没有通过该功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多