繁体   English   中英

Elastic Search - 对嵌套文档进行排序和过滤

[英]Elastic Search - Sorting & Filtering on nested Documents

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

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

{
     "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 object 是 ES Query 将在其中查找价格并确定商品是有货还是缺货的地方。

我想添加更多子对象来存储(基本上是来自多个库存的数据)。 这可以 go 每个产品最多 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 查询应该查看嵌套的 object 并获取所有 50 家商店中最低的值(如果商品可用)。
  2. 性能不应降低。

挑战:

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

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

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

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

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

ElasticSearch自从引入聚合框架后就没有真正在切面方面讲过。 并不是它们不存在,只是它们的讨论方式不同。

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

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

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

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

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

回顾一下

功能要求:

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

是的,嵌套聚合将执行此操作。

  1. 性能不应降低。

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

挑战:

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

不,这应该不是问题

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

弹性聚合

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM