java - 如何折叠搜索结果中的重复项

标签 java spring-boot hibernate-search

我们将 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或者可能是 completion suggester .

如果您需要注册 Hibernate Search 不支持的类型的字段(例如 completion),这也是可能的:您只需要一个自定义桥。请参阅this example .

关于java - 如何折叠搜索结果中的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65182617/

相关文章:

java - 查找数组中相同的元素并防止重复计数

java - 如何为只读数据库表建立索引搜索?

java - Hibernate-Search 与许多 (90) 个实体类挂起。

java - 在java中按值传递对象

java - 如何使用 Square 的 Retrofit 网络库实现异步回调

java - 如何在 java 中查找二维 ArrayList 的列的唯一值?

spring-boot - 带 sitemesh 的 Spring Boot

java - Spring-Boot 1.4.0 使用随机端口示例

java - 多对多关系导致异常

hibernate - hibernate 搜索分页奇怪的行为