我目前不确定在Lucene中QueryParser与TermQuery的行为;我正在使用Lucene 3.6。
在我的示例中,我在相同的索引上尝试以下示例,其中相关字段设置为Field.Store.NO
和Field.Index.NOT_ANALYZED_NO_NORMS
。
Query q1 = new TermQuery(new Term("names", "test three"));
QueryParser q2p = new QueryParser(GenericIndexer.LUCENE_VERSION, "names", someAnalyzer);
Query q2 = q2p.parse("names:test three");
Query q3 = q2p.parse("names:\"test three\"");
在q2
和q3
两种情况下,我都无法重现与q1
相同的语法;通过打印查询,我可以看到:
names:test three
names:test names:three
names:"test three"
由于此差异,查询q2
和q3
不会返回任何结果,而查询q1
会返回预期结果。
问题:有没有办法让查询解析器重现与TermQuery相同的查询,或者我在这里错过了一些基本的Lucene概念?
注意:对于QueryParser,分析器与索引期间使用的分析器相同,但我不确定这些信息的相关性。
答案 0 :(得分:1)
使用TermQuery
,您将生成一个字词test three
。由于未对此字段进行分析,因此生成单个术语是正确的。
在q2中,由于查询解析器的语法,您会看到两个单独的术语。真正做的是,正在削减像这样的查询; names:test defaultField:three
,但由于您的默认字段也是“名称”
在q3中(你的注意事项确实非常相关!),你会产生一个短语查询,它与你在q1中提供的TermQuery
不完全相同,但是使用了正确的分析器,它可以是等价的。分析PhraseQueries,我猜测查询器解析器使用的分析器有StandardAnalyzer
,或类似的东西。区别在于术语的含义:
test
- three
test three
因此,两个表示之间没有相同的术语匹配。相反,请尝试使用KeywordAnalyzer
,这与使用未分析的字段有效。
您通常希望确保在QueryParser
中使用与分析文档相同的分析器,KeywordAnalyzer
是未分析字段的事实上的等效分析器。< / p>