为什么Lucene MatchAllDocsQuery“*:* AND name:a”和Hibernate搜索会产生错误的结果?

t5fffqht  于 2022-11-07  发布在  Lucene
关注(0)|答案(1)|浏览(136)

我有一个带有Hibernate搜索的Sping Boot 应用程序。
我的数据库包含2个条目:

  • 用户a的名称为a,用户B的名称为b。*

当我搜索*:* AND NOT name:a时,一切正常,我得到了 user B。(更新:这从来没有工作。)
当我搜索*:* AND name:a时,我得到了 user auser b(实际上是db中的所有元素)。奇怪的是,*:* AND name:b返回了预期的 user b!当我过滤其他属性(如 streetname)时,也会发生同样的事情。每当我搜索*:* AND xxxx:a时,我得到了所有的条目。
谁能解释一下为什么?
我就是这样搜索的

Analyzer analyzer = ftEm.getSearchFactory().getAnalyzer(Contact.class);
QueryParser parser = new LuceneQueryParser("description", analyzer, List.of("key"), List.of("startTime"));
Query luceneQuery = parser.parse("*:* AND streetname:a");
ftEm.createFullTextQuery(luceneQuery, Contact.class).getResultList();

Contact类的注解为

@Indexed
@AnalyzerDef(name = "sortTextAnalyzer", tokenizer = @TokenizerDef(factory = KeywordTokenizerFactory.class),
        filters = { @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
                @TokenFilterDef(factory = LowerCaseFilterFactory.class),
                @TokenFilterDef(factory = PatternReplaceFilterFactory.class,
                        params = { @Parameter(name = "pattern", value = "('-&\\.,\\(\\))"),
                                @Parameter(name = "replacement", value = " "),
                                @Parameter(name = "replace", value = "all") }),
                @TokenFilterDef(factory = PatternReplaceFilterFactory.class,
                        params = { @Parameter(name = "pattern", value = "([^0-9\\p{L} ])"),
                                @Parameter(name = "replacement", value = ""),
                                @Parameter(name = "replace", value = "all") }),
                @TokenFilterDef(factory = TrimFilterFactory.class) })
ctehm74n

ctehm74n1#

我不确定LuceneQueryParser是什么;它一定是您的一个自定义类。我假设它的工作是正确的。
我猜您没有为字段streetname指定特定的分析器?@AnalyzerDef只是:定义。就其本身而言,它对您的Map没有影响。您还需要将分析器分配给特定字段,例如:

@Field(analyzer = @Analyzer(definition = "sortTextAnalyzer"))
private String streetname;

如果做不到这一点,Hibernate Search 5将默认使用StandardAnalyzerStandardAnalyzer(在Hibernate Search 5 / Lucene 5中)的一个特殊之处是,它在分析过程中从文本中删除了常见的英语“停止词”。停止词是非常常见的词,没有什么意义:“那个”,“那个”,“for”,...还有,你猜对了,“a”。
所以本质上,我认为发生的是你的参数“a”被StandardAnalyzer分析了,导致了奇怪的行为。我希望它什么都不返回。也许是因为name:a被翻译成了name is empty,而只有文档a才能匹配它?也许是因为它与LuceneQueryParser的实现有关?也许是因为您实际上为字段name分配了一个分析器,而它与StandardAnalyzer并不 * 完全 * 相同?

相关问题