【发布时间】:2016-07-08 00:39:07
【问题描述】:
现在,我已经成功配置了一个基本的 Hibernate 搜索索引,以便能够在我的 JPA 实体的各个字段中搜索完整的单词:
@Entity
@Indexed
class Talk {
@Field String title
@Field String summary
}
我的查询看起来像这样:
List<Talk> search(String text) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager)
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Talk).get()
Query query = queryBuilder
.keyword()
.onFields("title", "summary")
.matching(text)
.createQuery()
FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(query, Talk)
return jpaQuery.getResultList()
}
现在我想微调这个设置,这样当我搜索“test”时,它仍然可以找到标题或摘要包含“test”的谈话,即使是另一个单词的前缀。因此,标题为“单元测试”或摘要包含“睾丸”的演讲仍应出现在搜索结果中,而不仅仅是标题或摘要包含“测试”作为完整单词的演讲。
我试图查看文档,但我不知道是否应该对我的实体的索引方式进行更改,或者它是否与查询有关。请注意,我想做类似以下的事情,但是很难搜索多个字段:
Query query = queryBuilder
.keyword().wildcard()
.onField("title")
.matching(text + "*")
.createQuery()
编辑: 根据 Hardy 的回答,我像这样配置了我的实体:
@Indexed
@Entity
@AnalyzerDefs([
@AnalyzerDef(name = "ngram",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = [
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class,
params = [
@Parameter(name = "minGramSize",value = "3"),
@Parameter(name = "maxGramSize",value = "3")
])
])
])
class Talk {
@Field(analyzer=@Analyzer(definition="ngram")) String title
@Field(analyzer=@Analyzer(definition="ngram")) String summary
}
由于该配置,当我搜索“arti”时,我会看到标题或摘要包含“arti”是(艺术家、手工等)子词的单词。不幸的是,在那之后我还得到了会谈,其中标题或摘要包含包含我的搜索词的子词(艺术、放屁等)的词。可能有一些微调可以消除这些,但至少我现在能更快地得到结果,而且它们的顺序很合理。
【问题讨论】:
标签: java hibernate jpa hibernate-search