solr QueryConverter的定制
其实我这里没有定制QueryConverter,只是基于此解决了一个问题。我在solr中引入suggest功能,Solr默认的QueryConverter为SpellQueryConvert,它是根据空格对查询参数做分隔,导致
“nokia
e”这样的字符被当作“nokia”,“e”这样的两个字符处理,不符合要求。例如索引中有数据“nokia
email”,我需要“nokia
e”作为一个整体处理获取suggestions,而分成“nokia”,“e”两个字符处理得到的数据并不是想要的。
方法一:找到SpellCheckComponent类加断点调试发现那里有个判断函数,会先取spellcheck.q的值,如果不为空,按其值处理获得token
stream处理,如果为空,则按q获取值处理得到tokens
stream,这里这两个处理并不一样:
String q = params.get(SPELLCHECK_Q);
if (q != null) {
//we have a spell check param, tokenize it with the query analyzer
applicable for this spellchecker
tokens = getTokens(q, spellChecker.getQueryAnalyzer());
} else {
q = rb.getQueryString();
if (q == null) {
q = params.get(CommonParams.Q);
}
tokens = queryConverter.convert(q);
}
前者处理“nokia e”后得到的token还是“nokia
e”,而后者处理后得到的token为[nokia,e],也就是说前者才是符合我们需求的,所以在solrj中suggest功能模块用spellcheck.q查询。
方法二:在solrconfig中添加
<queryConverter name=”phraseQueryConverter”/>
调试源码时发现还有一个SuggestQueryConverter类,与SpellQueryConvert一样继承QueryConverter类,查看官方WIKI解释发现
queryConverter默认值是SpellQueryConvert,这里加入配置改成SuggestQueryConverter即可,无需再定制QueryConverter,当然你可以定制QueryConverter实现你所需要的需求。其实这里的SuggestQueryConverter中和方法一if中的处理是一样的。实现结果如下:
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
</lst>
<lst name="spellcheck">
<lst name="suggestions">
<lst name="motorola x">
<int name="numFound">10</int>
<int name="startOffset">0</int>
<int name="endOffset">10</int>
<arr name="suggestion">
<str>motorola xoom 3g版</str>
<str>motorola xt875</str>
<str>motorola xt300</str>
<str>motorola xt883</str>
<str>motorola xt702</str>
<str>motorola xt806</str>
<str>motorola xt800</str>
<str>motorola xt502</str>
<str>motorola xt882</str>
<str>motorola xt316</str>
</arr>
</lst>
<str name="collation">motorola xoom 3g版</str>
</lst>
</lst>
</response> (这里引用的数据来自于http://www.colorfuldays.org/tag/solr/)