如果我在值的末尾添加通配符,为什么我的Lucene仅匹配字段

时间:2018-08-15 09:06:00

标签: java lucene

如果我在值的末尾添加通配符,为什么我的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

3 个答案:

答案 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问题并重新部署了最新的代码库,现在搜索按预期进行。