我有两个文档4349
和P 43
。
P 43
的搜索字符串按顺序返回
4349
P 43
我的索引def如下所示
@AnalyzerDefs({
@AnalyzerDef(
name = "ngram",
charFilters = {
@CharFilterDef(factory = HTMLStripCharFilterFactory.class)
},
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class, params = {
@Parameter(name = "words", value = "/org/apache/lucene/analysis/snowball/english_stop.txt")}),
@TokenFilterDef(factory = EdgeNGramFilterFactory.class, params = {
@Parameter(name = "maxGramSize", value = "1"),
@Parameter(name = "maxGramSize", value = "15")
})
}
),
我的搜索def在没有ngramfilter的情况下是相同的,我已经关闭了lengthnorm。
问:如何将第二名作为更高的比赛返回或者返回的名单排名是否正常?
问:短语的另一种方法是如何考虑或已经采用输入查询中的令牌顺序?
我能够使用querybuilder.phrase().withSlop(10)...sentence('P 43')
但现在它不再返回第一个结果而只返回第二个结果
答案 0 :(得分:0)
您需要了解您的Analyzer定义如何分解您的条款。
使用这样的 EdgeNGramFilterFactory ,您的 4349 将按照以下标记进行转换:
4349
- > [4
,43
,434
,4349
] 虽然“P 43”将被类似地拆分,但只有在将“P”与“43”分开之后,因为您还有 StandardTokenizerFactory :
P 43
- > [p
,4
,43
] 所以这些标记会插入到倒排索引中。
在查询时,句子“P 43”将使用相同的方法分割:
P 43
- > [p
,4
,43
] 您的文档将包含所有4
和43
,就像您的查询所要求的那样。所以这两个文件都匹配。
现在,如果您重复测试但禁用基于N-Gram的过滤器,我们将使用不同的索引:
4349
- > [4349
] P 43
- > [p
,43
] 您的查询将是:
P 43
- > [p
,43
] 只有第二个文档与p
或43
这两个词中的任何一个匹配,因此只有第二个文档才会被视为匹配。
我建议使用辅助类 org.hibernate.search.util.AnalyzerUtils ,这是我用来确认将为每个输入/分析器配置生成哪些令牌。
Analyzer analyzer = searchFactory.getAnalyzer( "ngram" );
System.out.println( AnalyzerUtils.tokenizedTermValues( analyzer, "description", "4349" ) );
System.out.println( AnalyzerUtils.tokenizedTermValues( analyzer, "description", "P 43" ) );