如果我在值的末尾添加通配符,为什么我的Lucene 4.10仅匹配字段?
我有一个用关键字分析器定义的名为acoustid的字段
4999999950000000
Total time: 8.002650737762451
如果我这样运行查询,将找不到匹配项
ACOUSTID("acoustid",IndexFieldTypes.TEXT_NOT_STORED_ANALYZED_NO_NORMS, new KeywordAnalyzer()),
但是如果添加通配符,我会得到正确的匹配
query=acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855
请注意,在转到Lucene之前,对Lucene的查询已转义
我还有另一个字段(reid),该字段也使用KeywordAnalyzer存储了Guid 效果很好。
query=acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855*
我不明白这一点,因为我看不到该值之后怎么会有其他数据,而且我的单元测试(例如
)query=reid:425cf29a-1490-43ab-abfa-7b17a2cec351
它工作正常。
下一步是什么?
更新
记得我添加了一个选项来解释查询,所以这是通配符
@Test
public void testFindReleaseByAcoustId() throws Exception {
Results res = ss.search("acoustid:1d9e8ed6-3893-4d3b-aa7d-6cd79609e389", 0, 10);
assertEquals(1, res.getTotalHits());
assertEquals("1d9e8ed6-3893-4d3b-aa7d-6cd79609e386", getReleaseId(res.results.get(0).getDoc()));
}
这是没有
Query:+acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855* +src:1
0:Score:100.0
ba938fab-22b1-42ba-9bda-47261bc0569d:Now That's What I Call the 90s
2.954172 = (MATCH) sum of:
0.3385043 = (MATCH) ConstantScore(acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855), product of:
1.0 = boost
0.3385043 = queryNorm
2.6156676 = (MATCH) weight(src:1 in 9) [DefaultSimilarity], result of:
2.6156676 = score(doc=9,freq=1.0 = termFreq=1.0 ), product of:
0.9409648 = queryWeight, product of:
2.779772 = idf(docFreq=2052700, maxDocs=12169449)
0.3385043 = queryNorm
2.779772 = fieldWeight in 9, product of:
1.0 = tf(freq=1.0), with freq of:
1.0 = termFreq=1.0
2.779772 = idf(docFreq=2052700, maxDocs=12169449)
1.0 = fieldNorm(doc=9)
很显然,“-”连字符引起了破坏术语的问题。
我对相似的Query:+(acoustid:ae8f4538 acoustid:9971 acoustid:41b3 acoustid:a6d0 acoustid:bbca1c13e855) +src:1
的工作查询给出了
查询:+ reid:c3c0e462-1606-40dc-9667-1b26b9fb44c5 + src:1
reid
啊,我可能已经找到问题了,但是必须重建索引才能检查
reid被定义为使用IndexFieldTypes。TEXT_STORED_ NOT_ANALYZED _NO_NORMS 已定义助听器以使用IndexFieldTypes.TEXT_NOT_STORED_ ANALYZED _NO_NORMS
答案 0 :(得分:1)
请尝试以下操作:
WildcardQuery q = new WildcardQuery(new Term("acoustid", "ae8f4538-9971-41b3-a6d0-bbca1c13e855*");
q.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_REWRITE);
Query rewritten = searcher.rewrite(q);
并查看重写的查询(通过toString()
或调试器)。
rewritten
将是由单项查询子句组成的布尔查询,反映了真实的索引项。
UPD :在Lucene4中,中间行应为
q.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
答案 1 :(得分:1)
由于我不知道ss
是什么,因此无法在此处给出超级具体的答案。我假设它是写在您的应用程序中的层,以简化运行Lucene搜索和管理读者的工作。
我假设ss.search
类似于:获取索引读取器,打开queryparser并解析查询字符串,运行查询,返回Results
您的应用程序知道如何读取。
这里的问题步骤是queryparser。 QueryParser通过了分析器,如果分析器与您搜索的字段不匹配,则会遇到问题。如果使用StandardAnalyzer分析GUID,最终将得到一个查询,即后期分析,类似于:
acoustid:"ae8f4538 9971 41b3 a6d0 bbca1c13e855"
与索引中的显示方式不匹配。通配符查询之所以有效,是因为通配符查询(和模糊查询等)会跳过分析。
对于reid
为何起作用,不确定,我必须看看ss.search
是什么样。但是,如果我敢打赌,我敢打赌,您会发现一个PerFieldAnalyzerWrapper,该reid为此设置了KeywordAnalyzer,而acoustid没有。在这种情况下,请使用fieldAnalyzers
将助听剂添加到KeywordAnalyzer
列表中,您就很好了。
答案 2 :(得分:1)
由前两个答案辅助,问题是查询分析器与索引时使用的分析器不同。 但这不是编码错误,而是部署错误。
当我上次部署索引时,正在对两个新字段进行索引(不是上面的字段),因此定义了用于索引不同字段的分析器的索引代码和类已被更改。但是当时我没有部署更新的搜索器代码,因为搜索器代码本身并未更改,但是搜索器代码使用的索引库已更改。
实际上我确实尝试部署最新的搜索代码,但是我还遇到了另一个有关JAXB和Java 8 / Java 10的问题,然后阻止了部署。因为我认为我还是不需要重新部署,所以我离开了它。
而且由于问题出在旧字段acoustid
而不是新字段上,所以我没有意识到问题是新问题。
无论如何,我解决了JAXB问题并重新部署了最新的代码库,现在搜索按预期进行。