您现在的位置:首页 >> 前端 >> 内容

搜索关键字拼音智能提示实现

时间:2017/7/27 13:43:57 点击:

  核心提示:一、背景搜索的智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,提升用户体验。由于中文的特点,如果搜索自动提示可以支持拼音的话会给用户带来更大的方便,免得...

一、背景

搜索的智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,提升用户体验。

由于中文的特点,如果搜索自动提示可以支持拼音的话会给用户带来更大的方便,免得切换输入法。

目前大多数的电子商务网站都支持拼音提示功能。

二、目标

  • 基于用户的历史搜索关键字进行提示
  • 同时支持汉字,拼音输入
  • 支持前缀匹配,比如输入“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:


    ----------------------------------------------

    ----------------------------------------------




    synonyms="synonyms.txt"
    ignoreCase="true"
    expand="true" />
    ignoreCase="true"
    words="stopwords.txt"
    enablePositionIncrements="true" />





    ignoreCase="true"
    words="stopwords.txt"
    enablePositionIncrements="true" />


     

    solrconfig.xml


    suggest_text

    suggest
    org.apache.solr.spelling.suggest.Suggester
    org.apache.solr.spelling.suggest.tst.TSTLookup
    suggest
    0
    true



    default
    suggest
    solr.DirectSolrSpellChecker
    internal
    0.2
    2
    1
    50
    2
    0.01



    wordbreak
    solr.WordBreakSolrSpellChecker
    suggest
    true
    true
    10







    true
    default
    wordbreak
    suggest
    true
    10
    true



    suggest

     

    配置完成后,启动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建立索引,

    https://localhost:8983/solr/collection1/suggest?q=cq&spellcheck.build=true&distrib=false

    而后:

    https://localhost:8983/solr/collection1/suggest?q=cq&distrib=false

    存在问题

    该方法存在的问题是:

    返回的结果是基于索引中字段的词频进行排序,不是用户搜索关键字的频率,因此不能将一些热门关键字排在前面(网上有人提到定制SuggestWordScoreComparator来实现)

    拼音提示,多音字,缩写还是要另外加索引字段

    2. Solrcloud建立单独的collection,利用solr前缀查询实现

    配置如下:

    solr.xml:



    cp -r collection1 collection2

    修改collection2中的schema.xml和solrconfig.xml

    schema.xml:

    -----------------------fields--------------------------------

    ------------------multiValued表示字段是多值的-------------------------------------

    注:

    kw为原始关键字

    pinyin和abbre的multiValued=true,在使用solrj建此索引时,定义成集合类型即可:如关键字“重庆”的pinyin字段为{chongqing,zhongqing}, abbre字段为{cq, zq}

    kwfreq为用户搜索关键的频率,用于查询的时候排序

    ------------------uk----------------------------------

    kw

    suggest

    -------------------------------------------------------

    ------------------suggest_text----------------------------------

    synonyms="synonyms.txt"

    ignoreCase="true"

    expand="true" />

    ignoreCase="true"

    words="stopwords.txt"

    enablePositionIncrements="true" />

    ignoreCase="true"

    words="stopwords.txt"

    enablePositionIncrements="true" />

    启动命令:

    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强调的查询功能,数组和正则匹配。参考/database/201203/123450.html

    经过测试,效果与方案2类似。

    四、总结

    以上三个方案都能实现搜索关键字智能提示,方案1还需要研究完善才能实现基于用户搜索频率热词排序,方案3需要另外部署mongodb服务,不利用维护,所以本人在实际项目中采用了方案2.

作者:网络 来源:lanxin888的