功能需求
全文檢索搜尋引擎都會有這樣一個功能:輸入一個字元便自動提示出可選的短語:
要實現這種功能,可以利用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>
這裡
測試
通過瀏覽器位址列輸入連線測試:
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做其他業務需求。