Java 若我在值的末尾添加通配符,为什么我的Lucene只匹配字段
为什么我的Lucene 4.10只有在值的末尾添加通配符时才匹配字段 我有一个用KeywordAnalyzer定义的名为ausonID的字段Java 若我在值的末尾添加通配符,为什么我的Lucene只匹配字段,java,lucene,Java,Lucene,为什么我的Lucene 4.10只有在值的末尾添加通配符时才匹配字段 我有一个用KeywordAnalyzer定义的名为ausonID的字段 ACOUSTID("acoustid",IndexFieldTypes.TEXT_NOT_STORED_ANALYZED_NO_NORMS, new KeywordAnalyzer()), 如果像这样运行查询,则不会得到匹配项 query=acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855 但如果添加通配符,我
ACOUSTID("acoustid",IndexFieldTypes.TEXT_NOT_STORED_ANALYZED_NO_NORMS, new KeywordAnalyzer()),
如果像这样运行查询,则不会得到匹配项
query=acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855
但如果添加通配符,我会得到正确的匹配
query=acoustid:ae8f4538-9971-41b3-a6d0-bbca1c13e855*
注意,在到达Lucene之前,对Lucene的查询进行转义
我有另一个字段(reid),它也使用KeywordAnalyzer存储GUI
这很好
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=reid:425cf29a-1490-43ab-abfa-7b17a2cec351
我的下一步应该是什么
更新
刚刚记得我添加了一个选项来解释查询,所以这是通配符
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
的工作查询给出
查询:+reid:c3c0e462-1606-40dc-9667-1b26b9fb44c5+src:1
0:Score:100.0
c3c0e462-1606-40dc-9667-1b26b9fb44c5:Liquid Tension Experiment
16.852135 = (MATCH) sum of:
16.39361 = (MATCH) weight(reid:c3c0e462-1606-40dc-9667-1b26b9fb44c5 in 552496) [DefaultSimilarity], result of:
16.39361 = score(doc=552496,freq=1.0 = termFreq=1.0 ), product of:
0.9863018 = queryWeight, product of:
16.621292 = idf(docFreq=1, maxDocs=12169449)
0.059339657 = queryNorm
16.621292 = fieldWeight in 552496, product of:
1.0 = tf(freq=1.0), with freq of:
1.0 = termFreq=1.0
16.621292 = idf(docFreq=1, maxDocs=12169449)
1.0 = fieldNorm(doc=552496)
0.4585254 = (MATCH) weight(src:1 in 552496) [DefaultSimilarity], result of:
0.4585254 = score(doc=552496,freq=1.0 = termFreq=1.0 ), product of:
0.16495071 = queryWeight, product of:
2.779772 = idf(docFreq=2052700, maxDocs=12169449)
0.059339657 = queryNorm
2.779772 = fieldWeight in 552496, 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=552496)
啊,我可能已经发现了问题,但必须重建索引以进行检查
reid定义为使用索引字段类型。存储的文本未分析
声波ID被定义为使用索引字段类型。未存储的文本\uu已分析\u无规范请尝试以下操作:
WildcardQuery q = new WildcardQuery(new Term("acoustid", "ae8f4538-9971-41b3-a6d0-bbca1c13e855*");
q.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_REWRITE);
Query rewritten = searcher.rewrite(q);
并查看重写的查询(通过toString()
或调试器)。
重写的
将是从单项查询子句生成的布尔查询,反映实际索引项
UPD:在Lucene4中,中间线应为
q.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
这里不能给出一个超级具体的答案,因为我不知道什么是
ss
。我假设它是在您的应用程序中编写的,以简化运行lucene搜索和管理读卡器,诸如此类的事情
我假设ss.search
看起来像:获取一个indexreader,打开一个queryparser并解析查询字符串,运行查询,返回应用程序知道如何读取的结果
这里的问题步骤是queryparser。QueryParser通过一个分析器,如果分析器与您搜索的字段不匹配,您就会遇到问题。如果您使用StandardAnalyzer分析GUID,您将得到一个查询,post analysis,它类似于:
acoustid:"ae8f4538 9971 41b3 a6d0 bbca1c13e855"
与它在索引中的显示方式不匹配。通配符查询可以工作,因为通配符查询(和模糊查询等)跳过分析
至于为什么reid
有效,我不确定,我必须看看ss.search
是什么样子。然而,如果我要打赌的话,我敢打赌你会找到一个,reid已经为它设置了一个关键字分析器,但是Souadoid没有。在这种情况下,使用关键字分析器向fieldAnalyzers
列表中添加audioId,就可以了。在前面两个答案的帮助下,问题在于查询分析器与索引时使用的分析器不同但这不是编码错误,而是部署错误。
当我上次部署索引时,有两个新字段正在被索引(而不是上面的字段),因此定义用于索引不同字段的分析器的索引代码和类发生了变化。但当时我没有部署更新的搜索程序代码,因为搜索程序代码本身没有更改,但搜索程序代码使用的索引库已经更改
我确实尝试过部署最新的搜索代码,但我也遇到了另一个关于JAXB和Java8/Java10的问题,然后是防止3ED解聚。因为我认为我无论如何都不需要重新部署,所以我离开了它
由于问题出在一个旧的领域,而不是一个新的领域,我没有意识到这个问题是一个新的问题
无论如何,我解决了JAXB问题,并使用最新的代码库重新部署,现在搜索工作正常。连字符(-
)不是lucene查询中的特殊字符吗?布尔运算符允许通过逻辑运算符组合术语。Lucene支持AND、“+”、OR、NOT和“-”作为布尔运算符(注意:布尔运算符必须都是大写)。
@XtremeBaumer算作我的答案……连字符不会被解析为运算符,除非它出现在一个有效的位置,基本上在一个空格(不在一个短语中)之后。这将被解析为一个操作符:字段:term-term2
,而这不会:字段:hypenated term
(这也不会:字段:“短语-术语”
),所以所有的问题是,您的查询是针对声学ID
字段进行分析的。但菲尔德不是。据我记忆所及,KeywordAnalyzer
是KeywordTokenizer
的包装器,因此不会在QParser中进行拆分。。。看起来像是一个小错误,比如查询分析器和索引分析器是不一样的。我不明白你在这里得到了什么,为什么我需要使用通配符查询我建议一种调试方法。正如我从问题中得到的——通配符查询可以工作,但术语查询不行。所以我们需要找出通配符匹配的原因。布尔重写将在索引中显示(工作)通配符查询匹配的实数项。@Nikolay-我几乎可以保证一个术语查询(newtermquery(newterm(“aughousid”,“ae8f4538-9971-41b3-a6d0-bbca1c13e855”)
)实际上可以工作。谢谢你的回答提醒了我一些事情,我想我已经找到了答案,请参见更新IndexFieldTypes.TEXT\u NOT\u storage\u analysis\u NO\u norm像您使用的KeywordAnalyzer一样,它实际上不做任何分析。将其设置为“未分析”是有意义的,但“未分析”和“使用关键字分析器分析”之间没有任何功能差异。索引时间分析不是问题所在,这就是通配符查询工作的原因,问题在于QueryParser分析。试着在没有通配符的情况下运行一个解释,看看你是否在查询中得到了多个术语