本文目录
功能需求
全文检索搜索引擎都会有这样一个功能:输入一个字符便自动提示出可选的短语:
要实现这种功能,可以利用solr的SuggestComponent,SuggestComponent这种方法利用Lucene的Suggester实现,并支持Lucene中可用的所有查找实现。
实现
1. 配置 managed-schema文件
配置自己core文件夹conf下的managed-schema文件
这个是自己的字段:
<field name=\"name\" type=\"string\" indexed=\"true\" stored=\"true\"/>
<field name=\"username\" type=\"string\" indexed=\"true\" stored=\"true\"/>
<field name=\"password\" type=\"string\" indexed=\"true\" stored=\"true\"/>
<field name=\"phone\" type=\"string\" indexed=\"true\" stored=\"true\"/>
新建一个suggest_username字段,并将username的值拷贝到suggest_username字段:
<field name=\"suggest_username\" type=\"text_suggest\" indexed=\"true\" stored=\"true\"/>
<copyField source=\"username\" dest=\"suggest_username\"/>
copyField的source表示源,dest表示目标。
新建一个fieldType专门用于搜索建议:
<fieldType name=\"text_suggest\" class=\"solr.TextField\" positionIncrementGap=\"100\">
<analyzer>
<tokenizer class=\"solr.StandardTokenizerFactory\"/>
<filter class=\"solr.LowerCaseFilterFactory\"/>
<filter class=\"solr.EnglishPossessiveFilterFactory\"/>
</analyzer>
</fieldType>
-
tokenizer就是分词器,官方解释:
The job of a tokenizer is to break up a stream of text into tokens, where each token is (usually) a sub-sequence of the characters in the text。
就是指将文本流分解为标记tokens,这写tokens也是文本的子序列。
- 分词器tokenizer有很多种,详细信息见官网:
https://lucene.apache.org/solr/guide/8_1/tokenizers.html -
filter就是过滤器,官方解释:
The job of a filter is usually easier than that of a tokenizer since in most cases a filter looks at each token in the stream sequentially and decides whether to pass it along, replace it or discard it.
不同的过滤器将输入流替换或者丢弃或者直接通过。
- 过滤器也有很多种,官网详细信息:
https://lucene.apache.org/solr/guide/8_1/filter-descriptions.html
2. 配置solrconfig.xml文件
solrconfig.xml文件也在新建核心core的conf文件夹下
加入searchComponent
<searchComponent name=\"suggest\" class=\"solr.SuggestComponent\">
<lst name=\"suggester\">
<str name=\"name\">AnalyzingSuggester</str>
<str name=\"lookupImpl\">AnalyzingLookupFactory</str>
<str name=\"dictionaryImpl\">DocumentDictionaryFactory</str>
<str name=\"field\">suggest_username</str>
<str name=\"weightField\">suggest_username</str>
<str name=\"payloadField\">id</str>
<str name=\"suggestAnalyzerFieldType\">text_suggest</str>
<str name=\"buildOnStartup\">false</str>
</lst>
</searchComponent>
在searchComponent中的suggester需要配置一些参数。
- name ;suggest名字
- lookupImpl;查找不同算法实现,根据需要选择。
- dictionaryImpl;dictionaryImpl。
- field;建议的字段,如果是对多个字段做建议,就把多个字段拷贝到一个字段里面。即在定义filed的时候,定义为允许多值。
- weightField;表示权重。
- payloadField ;用于返回某一个值。
- suggestAnalyzerFieldType;field字段的类型。
-
buildOnStartup;启动的时候构建建议索引。
加入一个requestHandler用于建议:solr.SearchHandler
<requestHandler name=\"/suggest\" class=\"solr.SearchHandler\"
startup=\"lazy\" >
<lst name=\"defaults\">
<str name=\"suggest\">true</str>
<str name=\"suggest.count\">10</str>
</lst>
<arr name=\"components\">
<!-- 上面配置的searchComponent名字suggest -->
<str>suggest</str>
</arr>
</requestHandler>
这里 suggest 就是上面配置的searchComponent名字suggest。
测试
通过浏览器地址栏输入连接测试:
http://127.0.0.1:8983/solr/user/suggest?suggest=true&suggest.build=true&suggest.dictionary=AnalyzingSuggester&suggest.q=a
部分参数说明
- suggest.build=true ;表示构建suggest的索引,全部构建会耗时。可优化。
- suggest.dictionary=AnalyzingSuggester ;指明使用上面加入的suggester字典组件名字
-
suggest.q=a ;suggest查询内容。
请求具体参数地址:
https://lucene.apache.org/solr/guide/8_1/suggester.html#suggest-request-handler-parameters
返回结果
\"responseHeader\": {
\"status\": 0,
\"QTime\": 10
},
\"command\": \"build\",
\"suggest\": {
\"AnalyzingSuggester\": {
\"aoa\": {
\"numFound\": 3,
\"suggestions\": [
{
\"term\": \"aoa lee\",
\"weight\": 0,
\"payload\": \"7859b42e-3428-40c0-9036-6d50767a5ff2\"
},
{
\"term\": \"aoa lee key\",
\"weight\": 0,
\"payload\": \"0bead5d5-2570-44ba-830b-030f8a888ea3\"
},
{
\"term\": \"aoa lee key lol bob\",
\"weight\": 0,
\"payload\": \"9cc3c4d7-7d34-422b-8164-a4c4c92caa08\"
}
]
}
}
}
}
返回的结果中主要有三个参数:
- term ;表示命中的结果记录
- weight ;表示权重
- payload ;表示负载,也可用于返回某一个值,这里我们在searchComponent配置的 id 表示负载返回我们的id,可以通过id做其他业务需求。