我有一个hibernate搜索端点,需要返回一组单词中最接近的匹配项。当我尝试进行搜索时,在前10个结果中找不到最接近的单词,下面是hibernate搜索的片段
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Test.class).get();
org.apache.lucene.search.Query luceneQuery = qb.keyword().onFields("arg")
.matching(searchTerm).createQuery();
javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Test.class);
请问我怎样才能返回最接近的匹配词组
1条答案
按热度按时间kzipqqlq1#
虽然全文搜索可以返回“密切匹配”(即考虑到拼写错误等),但您仍然需要选择加入。
对于近似匹配,有两种解决方案:
使用“模糊”查询:这个解决方案是有限的,不太可配置,但设置起来很简单。
配置分析器。更具可配置性,但需要更多的知识。
如果您选择解决方案2,我建议您查看以下资源,以熟悉全文搜索:
什么是全文搜索
什么是分析
(这是HibernateSearch6的文档,但概念与HibernateSearch5相同)
然后看看如何在HibernateSearch5中配置分析器。
现在您应该对什么是分析器有了更好的了解:在索引和查询时,将文本转换为完全匹配的标记。近似匹配通过近似变换实现:如果分析变换“ré总和é" 输入“resume”,则查询“resume”将匹配包含“r”的文档é总和é".
例如:
查询中有一个输入错误。该文档的搜索点击率应该很高,但不会很高,因为只有一个词与“fox”匹配。
为了获得更多的近似匹配,一种策略是将单词分解成所谓的“ngrams”。为此,使用
NGramFilterFactory
,比如这里。如果我们设置分析,将单词分解为3克,我们将得到:
现在好一点了:两个词将匹配“ick”和“fox”。文档将在结果列表中处于较高的位置。
当然,这也不是完美的:
现在您将获得与可能无关的文档的匹配,例如包含“fickle”(=>“fic”,“ick”,“kle”)的文档。这应该通过相关性排序来抵消,将最佳匹配项放在结果列表的顶部附近:如果用户在顶部附近找到他想要的内容,他们不会介意其他结果是不相关的。
“borwn”这个词仍然没有被检测到匹配。你可以在3克的基础上再加2克,这样“wn”匹配,但要小心:你会得到更多不相关的匹配。
正如您所看到的,获得一个完全按照您想要的方式运行的全文搜索需要一些工作和配置;没有“一刀切”的解决方案。你只需要尝试不同的配置,看看什么最适合你。