solr6的学习与使用(五):联想词功能

来源:互联网 发布:开淘宝网店的流程 编辑:程序博客网 时间:2024/06/16 16:38

说到搜索,联想词功能肯定是必备的。为实现基于solr的联想词功能,做了大量的调研,最终在项目中实现了两种方案混用的形式。第一种是基于分词器推荐功能,即spellcheck;第二种是利用自己生成词库的方式去实现联想。那说一下这两种在solr里的实现方式吧。


  1. 首先是基于分词器推荐的方式,在solrconfig.xml中添加并设置suggest组件,实现如下:

在solrconfig.xml中修改如下配置,然后重启solr。

<searchComponent name="spellcheck" class="solr.SpellCheckComponent">  <str name="queryAnalyzerFieldType">text_ik</str>  <lst name="spellchecker">    <str name="name">default</str>    <str name="field">searchText</str>    <str name="buildOnCommit">true</str>    <str name="spellcheckIndexDir">spellchecker</str>  </lst></searchComponent><searchComponent class="solr.SpellCheckComponent" name="suggest">  <str name="queryAnalyzerFieldType">text_ik</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">searchText</str>    <!-- the indexed field to derive suggestions from -->    <float name="threshold">0.0001</float>    <str name="spellcheckIndexDir">spellchecker</str>    <str name="comparatorClass">freq</str>    <str name="buildOnOptimize">true</str>    <str name="buildOnCommit">true</str>  </lst></searchComponent><requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest"> <lst name="defaults">     <str name="spellcheck">true</str>     <str name="spellcheck.dictionary">suggest</str>     <str name="spellcheck.onlyMorePopular">true</str>     <str name="spellcheck.extendedResults">false</str>     <str name="spellcheck.count">10</str>     <str name=“spellcheck.collate">true</str>     <str name="spellcheck.maxCollations">5</str> </lst> <arr name="components">     <str>suggest</str> </arr></requestHandler><queryConverter name="phraseQueryConverter" class="org.apache.solr.spelling.SpellingQueryConverter"/>

需要说明的是,上面配置中主要注意field字段和queryAnalyzerFieldType字段的配置,前者是你再manage-scheme中配置过的field,后者是fieldType。下面是一个请求后的示例,访问URL为:http://[solr-sever-ip]:8983/solr/[coreName]/suggest?indent=on&q=防火设计&wt=json。

{  "responseHeader":{    "status":0,    "QTime":2},  "spellcheck":{    "suggestions":[      "防火",{        "numFound":7,        "startOffset":0,        "endOffset":2,        "suggestion":["防火门",          "防火墙",          "防火设计",          "防火阀",          "防火间距",          "防火堤",          "防火板"]},      "设计",{        "numFound":9,        "startOffset":2,        "endOffset":4,        "suggestion":["设计规范",          "设计标准",          "设计图",          "设计说明",          "设计方案",          "设计阶段",          "设计人",          "设计院",          "设计变更"]}],    "collations":[      "collation","防火设计规范",      "collation","防火门设计",      "collation","防火墙设计",      "collation","防火设计标准",      "collation","防火门设计规范"]}}

而我在联想词的选择中选择的不是suggestion(因为会对分词结果产生多个),最终我采用了collations(通过配置maxCollations设置想要的结果数)。然而这种效果不是非常理想,缺点就是当推荐的分词越来越长时,会产生语句不通的推荐。我的做法是通过一些策略过滤那种情况,然而为了更好的联想体验,我又实现了第二种方式的联想功能。


2. 基于自建联想词库方式。

首先创建一个新的core,方式参考之前的文章。然后修改配置文件solrconfig.xml,与上面基本一致,需要注意到sourceLocation为自建词库的地址,每次更改自建词库需要重启solr才能生效。

<searchComponent name="suggest" class="solr.SpellCheckComponent">  <str name="queryAnalyzerFieldType">text_ik</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">searchText</str>      <float name="threshold">0.0001</float>      <str name="sourceLocation">suggest/suggest.txt</str>      <str name="spellcheckIndexDir">spellchecker</str>      <str name="comparatorClass">freq</str>      <str name="buildOnOptimize">true</str>      <str name="buildOnCommit">true</str>  </lst></searchComponent><requestHandler name="/suggest" class="solr.SearchHandler">  <lst name="defaults">      <str name="spellcheck">true</str>      <str name="spellcheck.dictionary">suggest</str>      <str name="spellcheck.count">5</str>      <str name="spellcheck.onlyMorePopular">true</str>      <str name="spellcheck.extendedResults">false</str>      <str name="spellcheck.collate">true</str>      <str name="spellcheck.maxCollations">5</str>  </lst>  <arr name="components">      <str>suggest</str>  </arr></requestHandler>
这种方式也有弊端,如果你的自建词库不够全的话,会产生无推荐的情况。因此我最终将这两种方式同时运用,如果有比较好的方案,希望各位能够指点一下!多谢!






原创粉丝点击