编程语言
首页 > 编程语言> > java-前缀上的休眠搜索

java-前缀上的休眠搜索

作者:互联网

现在,我已经成功配置了基本的Hibernate Search索引,以便能够在我的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”作为完整词的谈话.

我试图查看文档,但是我不知道是否应该对实体的索引方式进行更改,或者是否与查询有关.请注意,我想执行以下操作,但是很难在几个字段中进行搜索:

 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”时,我得到了Talks,其中标题或摘要包含其词“ arti”是(艺术家,手工等)的子词的单词.不幸的是,在这些之后,我还获得了“对话”,其中标题或摘要包含包含我的搜索词(艺术,放屁等)的子词的单词.可能需要进行一些微调以消除这些问题,但是至少我现在能更快地得到结果,而且它们处于明智的顺序.

解决方法:

您可以在此处执行多项操作.通过在索引时间进行适当的分析,可以做很多事情.

例如,您想要应用适合您的语言的词干.对于英语来说,通常是Snowball词干.其想法是,在索引期间,所有单词都简化为词干,进行测试,然后测试为_test.这使您前进了一些.

您可以查看的另一件事是ngramm索引.根据您的描述,您还希望找到不相关词的匹配项.这里的想法是索引每个单词的“子单词”,以便以后可以找到它们.

关于分析器,您需要查看Hibernate Search文档的named analyzers部分.这里的关键是@AnalyzerDef批注.

在查询方面,您还可以应用一些“技巧”.确实,您可以使用通配符查询,但是,如果使用的是Hibernate Search查询DSL,则不能使用关键字查询,而需要使用通配符查询.再次,检查Hibernate Search文档.

标签:hibernate-search,jpa,hibernate,java
来源: https://codeday.me/bug/20191027/1942710.html