为什么 Lucene MatchAllDocsQuery "*:* AND name:a" 和休眠搜索会提供错误的结果?

Why does Lucene MatchAllDocsQuery "*:* AND name:a" and hibernate search deliver wrong results?

我有一个 Spring 带休眠搜索的启动应用程序。

我的数据库包含 2 个条目:

用户 a name=a 用户 b name=b.

当我搜索 *:* AND NOT name:a 时,一切正常,我得到 user b.(更新:这从来没有奏效。 )

当我搜索 *:* AND name:a 时,我得到了 user auser b (实际上是数据库中的所有元素) .奇怪的是 *:* AND name:b returns 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();

Contactclass注解为

@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) })

我不确定 LuceneQueryParser 是什么;它必须是您的自定义 class。我假设它的工作正常。

我猜你没有为字段分配特定的分析器 streetname@AnalyzerDef 就是:一个定义。就其本身而言,它对您的映射没有影响。您还需要将分析器分配给特定字段,例如:

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

否则,Hibernate Search 5 将默认为 StandardAnalyzerStandardAnalyzer(在 Hibernate Search 5 / Lucene 5 中)的一个特殊性是它在分析期间从文本中删除了常见的英语“停用词”。停用词是非常常见的词,意义不大:“the”、“that”、“for”……还有,你猜对了,“a”。

所以基本上,我认为正在发生的事情是您的论点“a”正在使用 StandardAnalyzer 进行分析,导致出现奇怪的行为。 我不能说为什么 *:* AND NOT name:a returns 文档 b;我希望它 return 什么都没有。也许是因为 name:a 被翻译成 name is empty,只有文档 a 会匹配?也许这与您实施 LuceneQueryParser 有关?也许您实际上为字段 name 分配了一个分析器,但它与 StandardAnalyzer?

完全 不一样