Solr 6.7学习笔记(04)-- Suggest
? ? ? ? 當我們使用baidu或者Google時,你輸入很少的字符,就會自動跳出來一些建議選項,在Solr里,我們稱之為Suggest,在solrconfig.xml里做一些簡單的配置,即可實現這一功能。配置如下:
<searchComponent name="suggest" class="solr.SuggestComponent"><lst name="suggester"><str name="name">mySuggester</str><str name="lookupImpl">FuzzyLookupFactory</str> <str name="dictionaryImpl">DocumentDictionaryFactory</str><str name="field">cat</str><str name="weightField">price</str><str name="suggestAnalyzerFieldType">string</str><str name="buildOnStartup">false</str></lst></searchComponent><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"><str>suggest</str></arr></requestHandler>元素 <searchComponent> 的屬性說明:
? ? name:指定searchComponent的名字。可以定義多個<searchComponent>,只要名字不一樣。在<requestHandler> --> <arr name="components"> --> <str> 里的值是指用哪個<searchComponent>。
? ?<lst name="suggester"> 的一些屬性
| 屬性 | 描述 |
| name | suggest的名字,用于區分多個suggest。在請求參數中加入suggest.dictionary=mySuggester來指定使用哪個suggester |
| lookupImpl | 查詢實現類,表示如何在Suggestions 字典中找到分詞(Term) |
| dictionaryImpl | 字典實現類,表示分詞(Term)是如何存儲Suggestion字典的 |
| field | 表示suggestion的內容是基于哪個字段的。這里設置的field的stored屬性必須是True。這可以設置為一個copyField,這樣suggetion 就可臺基于多個字段了。 |
| sourceLocation | 當dictionaryImpl為 FileDictionaryFactory時,指定此值,表示字典文件的路徑 |
| storeDir | 存儲字典文件的位置 |
| buildOnCommit | 默認值false。表示僅當請求的URL中包含suggest.build=true 時,才會創建 lookup的data。 為true時,表示lookup的data將在soft-commit后重新創建。 當索引比較大,尤其soft-commit很頻繁時,建議設置為FALSE。此時應該手動地在請求中加上suggest.build=true 去觸發構建lookup data的動作 |
| buildOnOptimize | 同上。區別是上面是soft-commit時,這里是索引優化時 |
| buildOnStartup | 設置為true,表示Solr啟動或者Core重新加載時,構建suggestions的data。如果沒有指定參數(文檔中并沒有說是設置為false),如果在磁盤上找不 到lookup data,則suggester將會構建它。通常建議設置成false,通過buildOnCommit中提到的方法去構建lookup data。 |
?
?
?
?
?
?
?
?
?
?
?
?
在同一個<searchComponent>里面,可以定義多個suggester (name 必須不一樣)。如:
<searchComponent name="suggest" class="solr.SuggestComponent"><lst name="suggester"><str name="name">fuzzySuggester</str><str name="lookupImpl">FuzzyLookupFactory</str> <str name="dictionaryImpl">DocumentDictionaryFactory</str><str name="field">cat</str><str name="weightField">price</str><str name="suggestAnalyzerFieldType">string</str><str name="buildOnStartup">false</str></lst><lst name="suggester"><str name="name">freeTextSuggester</str><str name="lookupImpl">FreeTextLookupFactory</str> <str name="dictionaryImpl">DocumentDictionaryFactory</str><str name="field">cat</str><str name="weightField">price</str><str name="suggestAnalyzerFieldType">string</str><str name="buildOnStartup">false</str></lst></searchComponent>定義多個Suggester后,我們可以在
1. <requestHandler>中指定使用哪個(或哪些)Suggester。如:
<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy" ><lst name="defaults"><str name="suggest">true</str><str name="suggest.count">10</str><str name="suggest.dictionary">freeTextSuggester</str><str name="suggest.dictionary">fuzzySuggester</str></lst><arr name="components"><str>suggest</str></arr></requestHandler>2. 使用Solrj 去連接Solr進行"/suggest" 查詢時,可以指定如下參數:
SolrQuery params = new SolrQuery(); params.set("qt", "/suggest"); params.set("suggest", "true"); //啟用Suggest params.set("suggest.build", "true"); params.set("suggest.dictionary", "fuzzySuggester"); params.set("suggest.dictionary", "freeTextSuggester");...3. 自己使用http去Get 時:
? http://localhost:8983/solr/techproducts/suggest?suggest=true&suggest.dictionary=fuzzySuggester&suggest.dictionary=freeTextSuggester&wt=json&suggest.q=elec
? ??
在<requestHandler name="/suggest">中的<lst name="defaults">里可以設置如下一些suggest的默認屬性,其值可被URL中相同的參數覆蓋
| 參數 | 描述 |
| suggest | 肯定設置為true |
| suggest.dictionary | suggester 的名字,可能過上面3種方法設置 |
| suggest.q | 在頁面上輸入的值。 |
| suggest.count | Solr返回的建議的分詞的數量 |
| suggest.cfq | 用于過濾suggestion的基于context field的 Context Filter Query。僅AnalyzingInfixLookupFactory 和 BlendedInfixLooupFactory? 支持此屬性,并且dictionaryImpl 必須是 Document*Dictionary |
| suggest.build | 如果為 true, 則會構建lookup data。通常不可能每次請求都去構建。使用情境見上面的buildOnCommit |
| suggest.reload | ?為true時,重新加載 suggester index |
| suggest.buildAll | ?為true時, 創建所有的suggester index。不明白和suggest.build有什么區別 |
| suggest.reloadAll | ?為true時,重新加載所有suggester index。不明白和 reload有什么區別 |
?
?
?
?
?
?
?
?
?
在程序員的世界里,學習任何語言或者技術,光看書是沒有用的。看的時候感覺都懂。實際做的時候就這也不會那也不會。還是得靠實踐。于是自己動手做了一個文件及其內容搜索的小程序,以此來加強對Solr的認識。設置了一些field:filename, filetype, filesize, content。這些用來存儲文件相關的信息,還有一個名為text的copyField,用于存儲所有值,以便查詢時只需指定一個field。定義如下:
<field name="filename" type="string" index="true" stored="true" /> <field name="filetype" type="string" index="true" stored="true" /> <field name="filepath" type="decent_path" index="true" stored="true" /> <field name="filetsize" type="tint" index="true" stored="true" /> <field name="content" type="text_general" index="false" stored="true" multiValues="true" /> <field name="text" type="text_general" index="true" stored="false" multiValues="true" /><copyField source="filename" dest="text" /> <copyField source="filetype" dest="text" /> <copyField source="filesize" dest="text" /> <copyField source="filepath" dest="text" /> <copyField source="content" dest="text" />?
使用suggester的時候遇到的一些問題:
1. 一開始,suggester的 field 設置的是 "text",我本想是讓所有的信息都可以做為建議項。用的是FuzzyLoopupFactory,可是發現建議項一直是空。不知道是哪邊出了問題,以為是copyField的問題,但是文檔寫了可以用copyField的。嘗試把field設置成"filename",可以出現建議項了。又仔細讀了一次文檔,發現原來“text”的stored屬性是false。改成true后,就成功了。
2. 另外,期間我也有把field 改成"content",它的stored值是true,indexed值是false。可是還是不能成功得到建議項。把indexed的值改成true,這時,content這個field的屬性和"text"是一樣的了,但是建議項一直為空!!上網搜了一下,網上也都是抄抄官方文檔的內容,找不到原因。突然發現suggester里面有一個suggestAnalyzerFieldType的屬性,其值為string (見本篇最開始部分的配置),再查了一下文檔,發現這是AnalyzingLookupFactory里的一個屬性,而FuzzyLookupFactory是繼承AnalyzingLookupFactory的,這個屬性指定的是查詢和創建suggest時,字段的類型。“content”的字段類型是text_general,而我配置的是string,所以找不到建議項。改成text_general后 -- 納尼?還是查不到建議項。看了一下我的程序的日志,發現是有建議項的,只不過建議的內容是整個文件的內容,太長了。可能是前端jQuery的suggest組件會把過長的建議項刪除。因此UI 上看不到。但是后臺確實是有建議項的。注意:輸入的內容必須是整個文件內容的開始字符。
3. 期間我也不小心索引了一個圖片文件,不是文本的文件。結果查詢時,拋了下面的exception。去掉這個圖片的索引后就好了。
Caused by: java.lang.StackOverflowError
??at org.apache.lucene.util.automaton.Operations.topoSortStatesRecurse(Operations.java:1288)
? at org.apache.lucene.util.automaton.Operations.topoSortStatesRecurse(Operations.java:1293)
? at org.apache.lucene.util.automaton.Operations.topoSortStatesRecurse(Operations.java:1293)
?
其實我想實現的Suggest是:如果有下面的一段文本,我在頁面的搜索框里輸入:man,會自動列出 manager,management和mana三個選項。
The manager of this management company is Mana.
但是上面配置的FuzzyLookupFactory,并不能實現這一需求。把suggester改成FreeTextLookupFactory,可以實現此需求。
<searchComponent name="suggest" class="solr.SuggestComponent"><lst name="suggester"><str name="name">mySuggester</str><str name="lookupImpl">FreeTextLookupFactory</str> <str name="dictionaryImpl">DocumentDictionaryFactory</str><str name="field">content</str><str name="weightField">content</str><str name="suggestFreeTextAnalyzerFieldType">text-general</str><str name="buildOnStartup">false</str><str name="buildOnCommit">true</str></lst></searchComponent>?
上一篇:
Solr 6.7學習筆記(02)-- 配置文件 managed-schema (schema.xml) -- 樣例(6)
轉載于:https://www.cnblogs.com/langfanyun/p/7459506.html
總結
以上是生活随笔為你收集整理的Solr 6.7学习笔记(04)-- Suggest的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery全选反选实例
- 下一篇: java 常量池详解