在Elasticsearch中,如何检索按销售商店分组的产品?

时间:2020-07-10 18:23:44

标签: elasticsearch

我有一堆商店,每个商店都出售几种产品,并且这些产品都有说明。我想建立一种搜索体验,使用户可以按描述中的单词搜索产品,并有一个搜索结果页面,其中显示匹配的产品,并按出售它们的商店进行分组。我的问题是:

如何设计一种高效的Elasticsearch模式和查询方案,使我可以查询按商店分组结果的产品,并确保搜索结果中的每个商店都包含与查询匹配的商品的完整列表? / p>


例如,假设我有以下数据:

  • 商店1
    • 产品1a,说明:“花生酱和果冻三明治”
    • 产品1b,说明:“炸玉米饼”
    • 产品1c,说明:“三明治夹”
  • 商店2
    • 产品2a,说明:“卷饼碗”
  • 商店3
    • 产品3a,说明:“三明治机”
    • 产品3b,说明:“三明治面包”
    • 产品3c,说明:“沙拉钳”

在我的整个应用程序中,我希望查询“三明治”以返回如下内容:

  • 商店1
    • 产品1a
    • 产品1c
  • 商店3
    • 产品3a
    • 产品3b

每当我显示一家商店时,我总是希望显示该商店的所有匹配。在我工作的领域中,有很多商店,但是每个商店只有少量产品(最多约10-20个,大多数商店只有2或3个)。

我可以看到两种方法来实现此目标,这两种方法对我来说都是不好的。

方法1

为每个产品建立索引是一个单独的文档。然后在查询时,我可以获取每个匹配的文档,并在Java中对其进行后期处理,以按存储对它们进行分组,最后返回该结果。我看到的这种方法的问题是:

  • 我无法使用任何排名,因为我将对结果进行重新排序。
  • 我也不能做任何限制;无论有多少文档,我都必须获取每个文档,因为否则我不能保证我拥有特定商店的所有产品。这将导致大量的工作浪费。

方法2

将每个商店的索引都作为一个单独的文档,并带有一个嵌套字段来保存每个产品。在查询时,我可以检索产品描述嵌套字段与搜索词匹配的商店。然后,一旦有了要显示的商店,就必须运行一个单独的查询以从这些商店中获取匹配的产品。这种方法的问题是:

    我要求Elasticsearch做比必要的更多的工作;内部,它在第一个查询中找到了我需要的所有内容,但无论如何我都在询问第二个查询
  • 发出两个相关查询会使代码复杂化,并要求我保持两个查询同步(例如,我需要确保在查询1中匹配的文档作为子字段与在查询2中匹配的文档相同)

除了我之外,对Elasticsearch更有经验的人可以找到更好的选择吗?

1 个答案:

答案 0 :(得分:1)

使用方法2,我看到2个选项:

  1. Nested inner hits

  2. 您可以使用top_hits with reverse_nested aggregator。您将搜索查询中的产品,并将文档按存储在聚合器中分组。 top_hits聚合返回常规搜索结果,这意味着您将获得子项(产品)以及父项(商店)。