如何折叠搜索结果中的重复项
How to collapse duplicates in search results
我们将 Hibernate Search 6 CR2 与 Elasticsearch 和 Spring Boot 2.4.0 结合使用。有什么方法可以折叠搜索结果中的重复项吗?
我们试图像这样“折叠”它们:
searchResults = searchSession.search(Items.class)
.select(f -> f.field(field.getCode(), String.class))
.where(f -> f.phrase()
.field(field.getCode())
.matching(phrase)
.slop(SLOP))
.fetchHits(20)
.stream()
.distinct()
.collect(Collectors.toList());
...但是此方法仅适用于少量结果(小于 fetchHits 大小)并且没有那么多相同的命中。当我们在另一个具有数千次点击(~28M 文档)的索引上尝试此方法时,我们发现由于 fetchHits 设置,它没有按预期工作——一些应该是的搜索结果——丢失了。当然,这里的主要问题是,通过使用这种方法,我们在搜索时不会区分搜索结果,它发生在原始搜索之后,所以它不是最好的解决方案。
在这里找到了另一个 solution,但它有点过时并且不是我们问题的实际答案。
在 Hibernate Search 论坛上,我们发现另一个 solution 用于类似的任务,我们尝试实现它并且它有效,但缺点是我们得到了索引文档字段的 2 倍乘法(现在是 8 个字段而不是 4 个) .
所以毕竟,是否可以在没有这些额外字段帮助的情况下调整 HS 以折叠搜索结果中的重复项?或者,如果可以的话……那好吧!我们会记住这一点,并在以后的案例中用作解决方案。
P.S.: 我们实现了按需搜索预测服务,因此无需提取原始实体。
The solution you linked 是获取给定字段的匹配文档中所有值列表的最直接方法。这就是聚合的目的。
是的,它需要额外的字段。一般来说,你不能凭空获得性能:要获得更小的执行时间,你需要使用更多的内存。
也就是说,如果您想要的是建议,您可能应该看看 Elasticsearch's suggester feature。
在 Hibernate Search 中(目前)还没有 API,因此您必须转换 JSON 才能利用此功能。这相对容易,你甚至有 an example for your very use case in the reference documentation(看第二个例子)。
当然如果真的要用词组查询的话,会比较复杂。我建议你看看 phrase suggester or maybe the completion suggester.
如果您需要注册一个 Hibernate Search 不支持的类型的字段(例如 completion
),也有可能:您只需要一个自定义桥。参见 this example。
我们将 Hibernate Search 6 CR2 与 Elasticsearch 和 Spring Boot 2.4.0 结合使用。有什么方法可以折叠搜索结果中的重复项吗?
我们试图像这样“折叠”它们:
searchResults = searchSession.search(Items.class)
.select(f -> f.field(field.getCode(), String.class))
.where(f -> f.phrase()
.field(field.getCode())
.matching(phrase)
.slop(SLOP))
.fetchHits(20)
.stream()
.distinct()
.collect(Collectors.toList());
...但是此方法仅适用于少量结果(小于 fetchHits 大小)并且没有那么多相同的命中。当我们在另一个具有数千次点击(~28M 文档)的索引上尝试此方法时,我们发现由于 fetchHits 设置,它没有按预期工作——一些应该是的搜索结果——丢失了。当然,这里的主要问题是,通过使用这种方法,我们在搜索时不会区分搜索结果,它发生在原始搜索之后,所以它不是最好的解决方案。
在这里找到了另一个 solution,但它有点过时并且不是我们问题的实际答案。
在 Hibernate Search 论坛上,我们发现另一个 solution 用于类似的任务,我们尝试实现它并且它有效,但缺点是我们得到了索引文档字段的 2 倍乘法(现在是 8 个字段而不是 4 个) .
所以毕竟,是否可以在没有这些额外字段帮助的情况下调整 HS 以折叠搜索结果中的重复项?或者,如果可以的话……那好吧!我们会记住这一点,并在以后的案例中用作解决方案。
P.S.: 我们实现了按需搜索预测服务,因此无需提取原始实体。
The solution you linked 是获取给定字段的匹配文档中所有值列表的最直接方法。这就是聚合的目的。
是的,它需要额外的字段。一般来说,你不能凭空获得性能:要获得更小的执行时间,你需要使用更多的内存。
也就是说,如果您想要的是建议,您可能应该看看 Elasticsearch's suggester feature。
在 Hibernate Search 中(目前)还没有 API,因此您必须转换 JSON 才能利用此功能。这相对容易,你甚至有 an example for your very use case in the reference documentation(看第二个例子)。
当然如果真的要用词组查询的话,会比较复杂。我建议你看看 phrase suggester or maybe the completion suggester.
如果您需要注册一个 Hibernate Search 不支持的类型的字段(例如 completion
),也有可能:您只需要一个自定义桥。参见 this example。