将相同的分析器应用于查询和字段

问题描述 投票:0回答:1

我正在尝试为我的API后端构建基本的搜索。用户传递任意查询,后端应该返回结果(显然)。我希望有一个与本地索引以及Elasticsearch一起使用的解决方案。

在我的实体上,我这样定义了一个分析器:

@AnalyzerDef(name = "ngram",
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
    filters = {
      @TokenFilterDef(factory = StandardFilterFactory.class),
      @TokenFilterDef(factory = LowerCaseFilterFactory.class),
      @TokenFilterDef(factory = StopFilterFactory.class),
      @TokenFilterDef(factory = NGramFilterFactory.class,
        params = {
          @Parameter(name = "minGramSize", value = "2"),
          @Parameter(name = "maxGramSize", value = "3") } )
    }
)

对于查询,我尝试了以下操作:

    FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(this.entityManager);
    Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");

    QueryParser queryParser = new MultiFieldQueryParser(ALL_FIELDS, analyzer);
    queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
    org.apache.lucene.search.Query query = queryParser.parse(queryString);


    javax.persistence.Query persistenceQuery = 
            fullTextEntityManager.createFullTextQuery(query, MyEntity.class);

    List<MyEntity> result = persistenceQuery.getResultList();

据我了解,我需要为查询提供一个分析器,以便对搜索查询进行“ ngram令牌化”并找到匹配项。之前,我使用过SimpleAnalyzer,结果,搜索仅匹配了完整的单词,我认为这支持了我的理论(对不起,我仍在学习此语言)。

上面的代码给了我NullPointerException:

java.lang.NullPointerException: null
        at org.hibernate.search.engine.impl.ImmutableSearchFactory.getAnalyzer(ImmutableSearchFactory.java:370) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
        at org.hibernate.search.engine.impl.MutableSearchFactory.getAnalyzer(MutableSearchFactory.java:203) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
        at org.hibernate.search.impl.SearchFactoryImpl.getAnalyzer(SearchFactoryImpl.java:50) ~[hibernate-search-orm-5.11.1.Final.jar:5.11.1.Final]

在线

Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");
hibernate-search
1个回答
1
投票

使用Elasticsearch集成时,您无法从Hibernate Search中检索分析器,因为在这种情况下,本地没有分析器:该分析器仅在Elasticsearch集群中远程存在。

如果只需要查询语法的子集,请尝试"simple query string" query:这是可以使用DSL构建的查询(因此它与Lucene和Elasticsearch相同),并且提供了最常见的功能(布尔查询,模糊性,词组...)。例如:

Query luceneQuery = queryBuilder.simpleQueryString()
    .onFields("name", "history", "description")
    .matching("war + (peace | harmony)")
    .createQuery();

语法有点不同,但这只是因为它针对最终用户并且试图变得更简单。

EDIT:如果不是简单查询字符串的选项,则可以手动创建分析器:即使使用Elasticsearch集成,该分析器也应该起作用。org.apache.lucene.analysis.custom.CustomAnalyzer#builder()应该是一个很好的起点。该类的javadoc中有几个示例。确保只创建一次分析器并将其存储在某个地方,例如以静态常量:创建分析器可能会很昂贵。

© www.soinside.com 2019 - 2024. All rights reserved.