一、背景
搜索的智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,提升用户体验。
由于中文的特点,如果搜索自动提示可以支持拼音的话会给用户带来更大的方便,免得切换输入法。
目前大多数的电子商务网站都支持拼音提示功能。
二、目标
- 基于用户的历史搜索关键字进行提示
- 同时支持汉字,拼音输入
- 支持前缀匹配,比如输入“ch”可能提示出“重庆”
- 支持缩写输入,比如输入“cq”能提示出“重庆”
- 多音字支持,比如输入“chongqing”或者“zhongqing”都能提示出“重庆”
- 输出结果,根据用户查询关键字的频率进行排序,暂时不考虑个性化需求
三、分析与解决方案
假设我们的搜索应用是基于solrcloud实现的,主要是对商家信息进行搜索,包括商家名称(store_name)、商家地址(address)。
(1). 用户每天输入大量的查询关键字,我们把查询的关键字记录下来,目前通过异步队列写入到mysql中,后期考虑写入到hbase中
(2). 用户输入的关键字可能是汉字、数字,英文,拼音,特殊字符等等,由于需要实现拼音提示,所以我们需要把汉字转换成拼音,java中考虑使用pinyin4j组件实现转换。
(3). 汉字转换拼音的过程中,顺便提取出拼音缩写,如“chongqing”,"zhongqing"--->"cq","zq"
(4). 要支持多音字提示,对查询串转换成拼音后,需要实现一个全排列组合,考虑到查询串可能比较长导致全排列比较的,具体算法需要做限制处理。
1. Solr Suggest实现智能提示
首先Solr作为一个应用广泛的搜索引擎系统,它内置了智能提示功能,叫做Suggest模块。该模块有两种可选方案做智能提示:
(1)、基于提示词文本做智能提示
(2)、基于索引中得某个字段建立索引词库做智能提示
配置如下:
schema.xml:
<field name="suggest" type="suggest_text" indexed="true" stored="false" multiValued="true" />----------------------------------------------
<copyField source="store_name" dest="suggest" />
<copyField source="address" dest="suggest" />
----------------------------------------------
<fieldType name="suggest_text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.SynonymFilterFactory"
synonyms="synonyms.txt"
ignoreCase="true"
expand="true" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />
</analyzer>
</fieldType>
solrconfig.xml
<searchComponent class="solr.SpellCheckComponent" name="suggest">
<str name="queryAnalyzerFieldType">suggest_text</str>
<lst name="spellchecker">
<str name="name">suggest</str>
<str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
<str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup</str>
<str name="field">suggest</str>
<float name="threshold">0</float>
<str name="buildOnCommit">true</str>
</lst>
<lst name="spellchecker">
<str name="name">default</str>
<str name="field">suggest</str>
<str name="classname">solr.DirectSolrSpellChecker</str>
<str name="distanceMeasure">internal</str>
<float name="accuracy">0.2</float>
<int name="maxEdits">2</int>
<int name="minPrefix">1</int>
<int name="maxInspections">50</int>
<int name="minQueryLength">2</int>
<float name="maxQueryFrequency">0.01</float>
</lst>
<lst name="spellchecker">
<str name="name">wordbreak</str>
<str name="classname">solr.WordBreakSolrSpellChecker</str>
<str name="field">suggest</str>
<str name="combineWords">true</str>
<str name="breakWords">true</str>
<int name="maxChanges">10</int>
</lst>
</searchComponent>
<requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest">
<lst name="defaults">
<str name="spellcheck">true</str>
<str name="spellcheck.dictionary">default</str>
<str name="spellcheck.dictionary">wordbreak</str>
<str name="spellcheck.dictionary">suggest</str>
<str name="spellcheck.onlyMorePopular">true</str>
<str name="spellcheck.count">10</str>
<str name="spellcheck.collate">true</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
配置完成后,启动solrcloud:
solr1:
java -Djetty.port=8983 -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DzkRun -DnumShards=1 -jar start.jar &
solr2:
java -Djetty.port=7574 -DzkHost=localhost:9983 -Dcollection.configName=myconf -DnumShards=1 -jar start.jar &
查询:
第一次查询时,添加spellcheck.build=true参数来触发spellckecker建立索引,
http://localhost:8983/solr/collection1/suggest?q=cq&spellcheck.build=true&distrib=false
而后:
http://localhost:8983/solr/collection1/suggest?q=cq&distrib=false
存在问题
该方法存在的问题是:
返回的结果是基于索引中字段的词频进行排序,不是用户搜索关键字的频率,因此不能将一些热门关键字排在前面(网上有人提到定制SuggestWordScoreComparator来实现)
拼音提示,多音字,缩写还是要另外加索引字段
2. Solrcloud建立单独的collection,利用solr前缀查询实现
配置如下:
solr.xml:
<cores adminPath="/admin/cores" defaultCoreName="collection1" host="${host:}" hostPort="${jetty.port:8983}" hostContext="${hostContext:solr}" zkClientTimeout="${zkClientTimeout:15000}">
<core name="collection1" instanceDir="collection1" />
<core name="collection2" instanceDir="collection2" />
</cores>
cp -r collection1 collection2
修改collection2中的schema.xml和solrconfig.xml
schema.xml:
-----------------------fields--------------------------------
<field name="kw" type="string" indexed="true" stored="true" />
<field name="pinyin" type="string" indexed="true" stored="false" multiValued="true"/>
<field name="abbre" type="string" indexed="true" stored="false" multiValued="true"/>
<field name="kwfreq" type="int" indexed="true" stored="true" />
<field name="_version_" type="long" indexed="true" stored="true"/>
<field name="suggest" type="suggest_text" indexed="true" stored="false" multiValued="true" />
------------------multiValued表示字段是多值的-------------------------------------
注:
kw为原始关键字
pinyin和abbre的multiValued=true,在使用solrj建此索引时,定义成集合类型即可:如关键字“重庆”的pinyin字段为{chongqing,zhongqing}, abbre字段为{cq, zq}
kwfreq为用户搜索关键的频率,用于查询的时候排序
------------------uk----------------------------------
<uniqueKey>kw</uniqueKey>
<defaultSearchField>suggest</defaultSearchField>
-------------------------------------------------------
<copyField source="kw" dest="suggest" />
<copyField source="pinyin" dest="suggest" />
<copyField source="abbre" dest="suggest" />
------------------suggest_text----------------------------------
<!-- suggest type-->
<fieldType name="suggest_text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.SynonymFilterFactory"
synonyms="synonyms.txt"
ignoreCase="true"
expand="true" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />
</analyzer>
</fieldType>
启动命令:
solr1:
java -Xms1024m -Xmx1024m -Djetty.port=8983 -Dbootstrap_conf=true -DzkHost=localhost:9983 -DnumShards=1 -jar start.jar &
solr2:
java -Djetty.port=7574 -DzkHost=localhost:9983 -DnumShards=1 -jar start.jar &
solrj前缀查询语法:
private SolrQuery getSuggestQuery(String prefix, Integer limit) {
SolrQuery solrQuery = new SolrQuery();
StringBuilder sb = new StringBuilder();
sb.append("kw:").append(prefix).append("*");
sb.append(" or pinyin:").append(prefix).append("*");
sb.append(" or abbre:").append(prefix).append("*");
solrQuery.setQuery(sb.toString());
solrQuery.addField("kw");
solrQuery.addField("kwfreq");
solrQuery.addSort("kwfreq", SolrQuery.ORDER.desc);
solrQuery.setStart(0);
solrQuery.setRows(limit);
return solrQuery;
}
3. mongodb实现拼音智能提示
实现原理类似于方案2,利用mongodb强调的查询功能,数组和正则匹配。参考http://www.2cto.com/database/201203/123450.html
经过测试,效果与方案2类似。
四、总结
以上三个方案都能实现搜索关键字智能提示,方案1还需要研究完善才能实现基于用户搜索频率热词排序,方案3需要另外部署mongodb服务,不利用维护,所以本人在实际项目中采用了方案2.
相关推荐
jQuery与Layui结合,可以实现高效且美观的前端功能,例如下拉框的搜索提示列表。这个功能允许用户在输入框中输入文字时,系统会自动匹配并展示相关的搜索结果,极大地提升了用户体验。 **一、jQuery简介** jQuery是...
`searchableSelect.js`是一款基于jQuery的输入框插件,专为实现模糊搜索和智能提示功能而设计。在网页表单中,用户经常需要从大量的数据中选择一个或多个项,传统的下拉列表可能无法满足高效查找的需求。这款插件...
`jquery.autocomplete`插件是jQuery的一个强大组件,它能够帮助我们实现智能提示和自动完成的功能。 首先,我们要理解`jquery.autocomplete.js`这个文件,它是实现自动补全功能的核心。这个插件允许开发者通过简单...
智能搜索联想功能的设计与实现涉及多个技术层面,包括关键字收集、汉字转拼音、拼音缩写提取以及高效的前缀匹配算法等。通过对上述技术方案的综合运用,可以有效提升用户的搜索体验,特别是在医疗、保险等行业中,...
关键字+空格, 神键手输入提示,代码智能补齐 双击Tab代码对齐, ALT+L字符串拼接, SHIFT+ENTER自动换行,括号自动补齐,代码区中文标点符号自动矫正,窗体控件批量生成 ,变量名及函数名中文拼音首字母输入提示, 代码行号
在列表框中实现首拼模糊查找,意味着用户只需要输入关键字的首拼音,系统就能智能地匹配并展示相关结果,无需精确输入每个字符。 实现"列表框首拼模糊查找支持中英文"的技术难点主要在于以下几点: 1. **首拼音...
关键字+空格, 神键手输入提示,代码智能补齐 双击Tab代码对齐, ALT+L字符串拼接, SHIFT+ENTER自动换行,括号自动补齐,代码区中文标点符号自动矫正,窗体控件批量生成 ,变量名及函数名中文拼音首字母输入提示, 代码行号 ...
除了基本的模糊查询,还可以结合其他技术,如 autocomplete 组件、拼音库和智能提示,提升用户搜索体验。例如,使用jQuery UI的Autocomplete插件,配合后台模糊查询接口,可以实时显示搜索建议。 总之,模糊查询在...
它提供了对树节点的智能搜索和过滤能力,允许用户通过输入拼音或汉字来查找和显示相关的树节点。 1. **ExtJS 3.3+ 中文API**: ExtJS是一个流行的JavaScript框架,用于构建富客户端应用。3.3版本的中文API文档可以...
16. 为了快速定位监控点,要求支持对监控点进行搜索,支持首字母查询,多关键字搜索。 17. 为满足用户不同监控显示需求,支持多窗口显示功能,支持1、4、6、8、9、10、13、14、16、17、22、25画面显示方式;支持...
2、程序智能化SEO设计:特别针对百度、谷歌等搜索引擎进行关键字优化设计,让客户快速找到您的网站; 3、程序操作简单:拥有完善的网站前台和后台全智能化管理功能,所有网站信息均可在后台进行更新,非专业人士也...
- **智能感知(Intellisense)**:在编写代码时提供实时的代码提示和补全建议,极大地提高了编码速度。 - **调试(Debugging)**:Visual Studio 2008提供了丰富的调试工具,包括断点、步进执行、变量观察等功能,帮助...
2、程序智能化SEO设计:特别针对百度、谷歌等搜索引擎进行关键字优化设计,让客户快速找到您的网站; 3、程序操作简单:拥有完善的网站前台和后台全智能化管理功能,所有网站信息均可在后台进行更新,非专业人士也...
2、程序智能化SEO设计:特别针对百度、谷歌等搜索引擎进行关键字优化设计,让客户快速找到您的网站; 3、程序操作简单:拥有完善的网站前台和后台全智能化管理功能,所有网站信息均可在后台进行更新,非专业人士也...
2、程序智能化SEO设计:特别针对百度、谷歌等搜索引擎进行关键字优化设计,让客户快速找到您的网站; 3、程序操作简单:拥有完善的网站前台和后台全智能化管理功能,所有网站信息均可在后台进行更新,非专业人士也...
2、程序智能化SEO设计:特别针对百度、谷歌等搜索引擎进行关键字优化设计,让客户快速找到您的网站; 3、程序操作简单:拥有完善的网站前台和后台全智能化管理功能,所有网站信息均可在后台进行更新,非专业人士也...