1.背景介绍
- Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过HttpGet操作提出查找请求,并得到XML格式的返回结果.在电商项目的检索场景下,存在因用户输入的搜索词汇不准确导致搜索结果不理想的情况。而solr的suggest模块可以合理的解决这一难题。
效果如下图:
2.项目配置
在此默认已经配置好了solr环境,配置suggest模块需要在solrhome下的solrcong.xml文件中加入如下配置:
<searchComponent name="suggest" class="solr.SpellCheckComponent">
<str name="queryAnalyzerFieldType">stringstr>
<lst name="spellchecker">
<str name="name">suggeststr>
<str name="classname">org.apache.solr.spelling.suggest.Suggesterstr>
<str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookupstr>
<str name="field">GOODSNAMEstr>
<float name="threshold">0.0001float>
<str name="sourceLocation">suggest.txtstr>
<str name="spellcheckIndexDir">spellcheckerstr>
<str name="comparatorClass">freqstr>
<str name="buildOnOptimize">truestr>
<str name="buildOnCommit">truestr>
lst>
searchComponent>
<requestHandler name="/suggest" class="org.apache.solr.handler.component.SearchHandler">
<lst name="defaults">
<str name="spellcheck">truestr>
<str name="spellcheck.dictionary">suggeststr>
<str name="spellcheck.count">11str>
<str name="spellcheck.onlyMorePopular">truestr>
<str name="spellcheck.extendedResults">falsestr>
<str name="spellcheck.collate">truestr>
lst>
<arr name="components">
<str>suggeststr>
arr>
requestHandler>
配置名称解释:
queryAnalyzerFieldType : schema.xml中的fieldType类型,如果加了这个选项,拼写检查时会调用这个fieldType的分词器,如果没有加,solr会取field属性上面filetype的分词器,这个时候还找不到,solr会创建一个按空格进行分词(SpellCheckComponent需要一个分词器才能运行),在这们项目中,我们现希望Analyzer不对查询做任何的改变,因此选择string。(网上也建议不要对他定义复杂的分词,如果指定的Analyzer很复杂的话,会导致suggest返回的结果不符合预期)
name:就是取个名字,江湖中的人士都是让他等于suggest
classname :org.apache.solr.spelling.suggest.Suggester(不要改动)
lookupImpl :org.apache.solr.spelling.suggest.Suggester(不要改动)
field : 说明只在这个字段上面做拼写检查
threshold :限制一些不常用的词出现,值越大过滤词就越多,取值范围【0~1】官网默认是0.005
comparatorClass : ellchecker组件中的comparatorClass参数可配置Suggest返回结果的排序,目前有如下几种可选方案:
a .Empty – in which case the default is used. 默认就是这个
b.score – explicitly choose the default case
c.freq – Sort by frequency first, then score. 通过频率的第一排序,然后得分 (开发时用这个)
d.A fully qualified class name – Provide a custom comparator that implements Comparato
buildOnCommit : 取值true或者flase,当commit的时候,对拼写检查索引进行构建。(只有构建后,拼写检查才有效果)
buildOnOptimize :当optimize的时候,对拼写检查索引进行构建。(只有构建后,拼写检查才有效果)
true : 开启检查建议
suggest :必须与searchComponent中spellchecker标签下suggest配置对应
8 :配置拼写检查提示结果的个数(可以根据需要适当加大)
true :等于true,可以根据权重排序,开发时我一般让他等于true
suggest : handler拥有的 components,first-components,last-components这三个属性的剖,Solr的handler都是同过这三个属性来取他所依赖的components(组件)
备注:handler在运行时,会加载5个默认的组件
a如果配置了components,则SOlr不会运行默认的5个组件。
而且你配置的first-components,last-components两个都是无效的。
b.如果配置了first-components,SOlr会给handler添加5个默认的组件时,同时会添加first-components配置的组件,而且这个组件最先工作。
c.同上,只不过放在最后工作
按照上述配置好项目后需要放置一个suggest.txt文本文件在solrcong.xml同级目录下
注意 : suggest.txt文件内容必须是utf-8的字符格式,不能用windows的记事本去编辑,可以用比如notepad一类工具编辑。或者在记事本编辑好了使用notepad转换文本格式,方法如下:
Suggest.txt文本内容即为人工维护的热搜词,示例如下:
3.测试
配置完成后重启solr服务器,访问主页,按照下图步骤即可看到推荐效果
4.项目配置
测试无误后即可将这一模块运用到项目中了,主体思想是:当用户在输入框输入内容后异步访问服务器,服务器返回数据到前台,列表展示。服务器代码如下:
public List<String> searchSuggest(String word) throws SolrServerException {
SolrQuery params = new SolrQuery();
params.set("qt", "/suggest");
params.setQuery("GOODSNAME:"+word);
QueryResponse queryResponse = getSolrServer(ResourceUtil.getConfigValueByName("solr.url")).query(params);
SpellCheckResponse suggest = queryResponse.getSpellCheckResponse();
List<Suggestion> suggestionList = suggest.getSuggestions();
List<String> suggestedWordList = new ArrayList<String>();
for (Suggestion suggestion : suggestionList) {
System.out.println("Suggestions NumFound: " + suggestion.getNumFound());
System.out.println("Token: " + suggestion.getToken());
suggestedWordList = suggestion.getAlternatives();
}
System.out.print("Suggested: "+queryResponse);
return suggestedWordList;
}
检索返回的结果如下:
{respOnseHeader={status=0,QTime=1},spellcheck={suggestiOns={笔={numFound=5,startOffset=10,endOffset=11,suggestion=[笔袋, 笔芯, 笔记本子, 笔记本电脑, 笔筒]},collation=GOODSNAME:笔袋}}}
文中部分内容摘自:http://eksliang.iteye.com/blog/2097924
水平有限,不免有误,不恰当的地方请指出,不胜感激!