我有一台分析仪,
searchMapping//
.analyzerDef(BaseEntity.CUSTOM_SEARCH_INDEX_ANALYZER, WhitespaceTokenizerFactory.class)//
.filter(LowerCaseFilterFactory.class)//
.filter(ASCIIFoldingFilterFactory.class)//
.filter(NGramFilterFactory.class).param("minGramSize", "1").param("maxGramSize", "200");
这是实体字段的配置方式
@Field(analyzer = @Analyzer(definition = CUSTOM_SEARCH_INDEX_ANALYZER))
private String bookName;
这是我创建搜索查询的方式
queryBuilder.keyword().onField(prefixedPath).matching(matchingString).createQuery()
我有一个实体的值为bookName=“Gulliver”,另一个实体的值为bookName=“xGulliver”;
如果我尝试用数据bookName = xG
进行搜索,那么我会得到两个实体,而我期望的是只有bookName="xGulliver"
的实体;还查看了由hibernate-search生成的查询。
正在执行Lucene查询'+(+(+(+(书名:x书名:xg书名:g))))
上面的Lucene查询是使用Lucene的BooleanJunction::must
条件准备的,我想这意味着它应该匹配所有的条件。但是为什么它给我两个实体数据。我不明白这里。
我还可以在查询时使用KeywordTokenizer而不是NGramFilterFactory来覆盖分析器,但这就像我必须在创建QueryBuilder之前覆盖每个字段一样,这看起来不太好,因为我必须覆盖所有索引字段,我有大约100个字段,其中一些是动态字段,我为每个字段创建单独的查询。
在5.11版本中是否有其他方法可以覆盖分析器,或者在hibernate-search 6.x版本中是否有其他更简单的方法?
我使用的Hibernate版本包括,
在这个例子中,我们使用了一个简单的方法,即:
1条答案
按热度按时间djmepvbi1#
上面的Lucene查询是用Lucene的BooleanJunction::must条件准备的,我想这意味着它应该匹配所有的条件。但是为什么它给我两个实体数据。我不明白这里。
使用Hibernate搜索创建
keyword
查询时,将分析传递给该查询的字符串,如果有多个标记,Hibernate搜索将为每个标记创建一个带有一个“should”子句的布尔查询。您可以在此处看到“bookName:x bookName:xg bookName:g”:在“bookName”前面没有“+”号,这意味着那些不是“must”子句,它们是“should”子句。我还可以在查询时使用KeywordTokenizer而不是NGramFilterFactory来覆盖分析器,但这就像我必须在创建QueryBuilder之前覆盖每个字段一样,这看起来不太好,因为我必须覆盖所有索引字段,我有大约100个字段,其中一些是动态字段,我为每个字段创建单独的查询。
是的,那很烦人。
在5.11版本中,是否有其他方法可以覆盖分析器
在5.11中,我不认为有任何其他方法可以覆盖分析器。
如果有必要并且您使用的是Lucene后端,我相信您应该能够绕过Hibernate Search DSL来执行以下特定查询:
Analyzer analyzer = fullTextSession.getSearchFactory().getAnalyzer("myAnalyzerWithoutNGramTokenFilter")
。analyzer.tokenStream(...)
并根据需要使用TokenStream
。您将获得一个令牌列表。Query
:本质上,它将是布尔查询,其中每个令牌有一个TermQuery
。Query
传递给Hibernate搜索。或者在hibernate-search 6.x版本中以其他方式更简单地处理它?
在Hibernate Search 6.0.0.Beta4中,这非常简单。有两种解决方案:
@FullTextField(analyzer = "myAnalyzer")
),还可以使用@FullTextField(analyzer = "myAnalyzer", searchAnalyzer = "mySearchAnalyzer")
指定“搜索”分析器。“默认”分析器将在索引时使用,而“搜索”分析器将在搜索(查询)时使用。.analyzer("mySearchAnalyzer")
来覆盖给定 predicate 上的分析器。文档的这一节中有一个示例。但是请注意,Hibernate Search 6中还不支持动态字段:HSEARCH-3273。