一、分面搜索
1. 什么是分面搜索?
分面搜索:在搜索結果的基礎上進行按指定維度的統計,以展示搜索結果的另一面信息。類似於SQL語句的group by
分面搜索的示例:
http://localhost:8983/solr/techproducts/browse
2. Solr中支持的分面查詢
字段分面、區間分面、決策樹分面、查詢分面
2.1 字段分面
執行搜索時,根據查詢請求返回特定分面字段中找到的唯一值以及找到的文檔數。
通用查詢參數:
facet:true/false 對當前搜索是否啟用分面
facet.query:指定一個額外的分面查詢語句
字段分面查詢參數:
facet.field:指定對哪個字段進行分面計算。該參數可以多次指定以返回多個字段方面。字段需是索引字段。
facet.sort:分面結果的排序方式:count:根據統計數量排,index: 索引的詞典順序
facet.limit:確定每個分面返回多少個唯一分面值。可取值:整數>=-1,-1表示不限制,默認100。
facet.offset:對分面值進行分頁,指定頁偏移。 >=0 默認0。
facet.prefix:指定限制字段分面值必須以xxx開頭,用以篩選分面值。
facet.missing:true/false,是否在分面字段中返回所有不包含值(值為缺失)的文檔計數。
facet.mincount:指定分面結果中的分面值的統計數量>=mincount的才返回
示例:
sort、limit、offset、prefix、missing、mincount 可根據字段指定: f.filedname.facet.sort=count
2.2 區間分面
區間分面將數值或時間字段值分成一些區間段,按區間段進行統計。
區間分面查詢參數:
facet.range:指定對哪個字段計算區間分面。可多次用該參數指定多個字段。 facet.range=price&facet.range=age facet.range.start:起始值 f.price.facet.range.start=0.0&f.age.facet.range.start=10 f.lastModified_dt.facet.range.start=NOW/DAY-30DAYS facet.range.end:結束值 f.price.facet.range.end=1000.0&f.age.facet.range.start=99 f.lastModified_dt.facet.range.end=NOW/DAY+30DAYS facet.range.gap:間隔值,創建子區間。對於數值字段,間隔值是數值,對於時間字段,用時間數學表達式(如+1DAY、+2MONTHS、+1HOUR等) f.price.facet.range.gap=100&f.age.facet.range.gap=10 f.lastModified_dt.facet.range.gap=+1DAY facet.range.hardend:如果間隔在下限和上限之間不是均勻分布,最后一個區間的大小要小於其他區間,當該參數為true時,最后區間的最大值就是上限值,如果為false,則最后區間會自動上擴,與其他區間等長。 facet.range.other 區間外的值是否統計,可選值: before: 統計<start的文檔數 after:統計>end的文檔數 between:統計區間內的 none:不統計 all:統計before、after、between的數量 facet.range.include:區間的邊界是如何包含的,默認是包含下邊界值,不包含上邊界值 (最后一個區間包含) 。可選值: lower:所有區間包含下邊界 upper:所有區間包含上邊界 edge:第一個區間包含下邊界,最后一個區間包含上邊界。 outer:范圍前“before” 和 后 “after”的統計區間將包含范圍的下邊界、上邊界。即使范圍內的區間包含了上、下邊界。 all:選擇所有選項:lower、upper、edge、outer Facet.mincount 也可使用。 注意:避免重復統計,不要同時選擇lower和upper、outer、all 可根據字段來指定: f.<fieldname>.facet.range.include
區間分面-練習:
在techproduct內核上進分面查詢:
1、按價格進行區間分面:10~10000 每間隔500一個區間
q=”:”&facet=true&facet.range=price&facet.range.start=10&facet.range.end=10000&facet.range.gap=500 參數說明: q=”:”-查詢所有的,&facet=true-打開分面查詢的開關 &facet.range=price-按照價格進行分面查詢 &facet.range.start=10&facet.range.end=10000-區間10到10000 &facet.range.gap=500-每間隔500一個區間 最終在瀏覽器輸入的地址為: http:localhost:8983/solr/techproducts?q=”:”&facet=true&facet.range=price&facet.range.start=10&facet.range.end=10000&facet.range.gap=500
2.3 查詢分面
直接通過facet.query參數指定查詢,來進行分面。
示例:
q=*:*&facet=true&facet.query=price:[* TO 5}&facet.query=price:[5 TO 10}&facet.query=price:[10 TO 20}&facet.query=price:[20 TO 50}&facet.query=price:[50 TO *] 說明: 通過facet.query指定需要查詢的區間:*-5,5-10,10-20,20-50,50-* 最終在瀏覽器輸入的地址為: http:localhost:8983/solr/techproducts?q=*:*&facet=true&facet.query=price:[* TO 5}&facet.query=price:[5 TO 10}&facet.query=price:[10 TO 20}&facet.query=price:[20 TO 50}&facet.query=price:[50 TO *]
2.4 決策樹分面
pivot(Decision Tree)faceting:決策樹分面,又稱多級分面。如想看對搜中商品的按類別統計結果,在類別下又想看它的流行度構成。
決策樹分面(多級分面)查詢參數:
facet.pivot:指定分級字段,以逗號間隔。可多個facet.pivot參數指定多個分級分面。 facet.pivot.mincount ;最少匹配文檔數,默認1。
示例:
facet.pivot=cat,popularity,inStock&facet.pivot=cat,inStock
說明:facet.pivot=cat,popularity,inStock表示先按照cat,再按照popularity分,最后按照inStock分
http://localhost:8983/solr/techproducts/select?q=*:*&facet.pivot=cat,popularity,inStock&facet.pivot=popularity,cat&facet=true&facet.field=cat&facet.limit=5&facet.pivot.mincount=2
key :Key 關鍵字用來對分面項進行重命名
q=*:*&facet=true&facet.query={!key="<5"}price:[* TO 5}&facet.query={!key="5-10"}price:[5 TO 10}&facet.query={!key="10-20"}price:[10 TO 20}&facet.query={!key="20-50"}price:[20 TO 50}
&facet.query={!key=">50"}price:[50 TO *]&facet.field={!key="類別"}ca
二、搜索結果高亮
1. 什么是搜索結果高亮
在搜索結果展示中突出顯示搜索的關鍵字。下圖是在百度中輸入solr進行搜索的一條結果: solr是紅色高亮的
2. 高亮參數說明:
hl:是否啟用高亮,默認false 。 hl.fl:要高亮處理的字段列表,可以逗號、空格間隔,可以使用通配符* hl.fl=name,feauts hl.tag.pre :高亮前綴,可以是任意字符串,一般為html、xml標簽,默認是<em> . (hl.simple.pre for the Original Highlighter) hl.tag.post:高亮后綴,默認是</em> hl.encoder :對字段值進行何種編碼處理,默認空,不做處理。如果指定為html,會對字段值中的html字符進行編碼處理:如 < 轉為 < & 轉為 & hl.maxAnalyzedChars :對字段值的最多多少個字符進行高亮處理,默認值51200 個字符。 hl.snippets :一個字段中可以有幾個高亮片段,默認1。 hl.fragsize :高亮片段的最大字符數,默認100,無上限。 hl.method:指定高亮的實現方式,可選值: unified, original, fastVector。默認是 original。 hl.q:如果你要高亮的詞不是主查詢中的詞,可通過此參數指定 hl.qparser:指定hl.q的查詢解析器 hl.requireFieldMatch:是否只是查詢用到的字段才高亮,默認false(hl.fl中指定的字段進行高亮處理)。 hl.usePhraseHighlighter:使用短語高亮,默認true。 hl.highlightMultiTerm:對於通配符查詢(多詞項查詢)是否高亮,默認true。
3. 高亮響應結果
高亮在響應結果中是獨立的一部分。
{ "response": { "numFound": 1, "start": 0, "docs": [{ "id": "MA147LL/A", "name": "Apple 60 GB iPod with Video Playback Black", "manu": "Apple Computer Inc.", }] }, "highlighting": { "MA147LL/A": { "manu": [ "<em>Apple</em> Computer Inc." ] } } }
4. 高亮的示例
http://localhost:8983/solr/techproducts/select?q=ipod&hl=true&hl.fl=name&hl.simple.pre=<span style='colr:red;font-size:20px'>&hl.simple.post=</span>
參數說明: q=ipod-查詢字段ipod,&hl=true-開啟高亮,&hl.fl=name-指定高亮的名稱為name,hl.simple.pre=<span style='colr:red;font-size:20px'>-指定高亮字段前綴的html樣式,&hl.simple.post=</span>-指定高亮字段后綴的樣式
高亮的特殊需求,請詳細參考官網的介紹:
https://lucene.apache.org/solr/guide/7_3/highlighting.html#usage
三、查詢建議
1. 拼寫檢查
拼寫檢查解決因查詢詞拼寫錯誤導致搜索結果不佳的問題。
拼寫檢查是搜索引擎的一個重要特征,幫助那些不想花時間構造查詢表達式的用戶,特別是移動環境中用戶。 針對用戶拼寫錯誤或關鍵字生僻,而搜索結果不佳,提供相近的詞建議。
1.1 拼寫檢查分析
拼寫檢查在什么情況下使用?
用戶輸入錯誤的,輸入的詞很生僻,命中結果很少
拼寫檢查組件應推薦什么樣的詞?
輸入相近的詞
拼寫檢查組件推薦的這些詞從哪來?
從索引里面來
1.2 拼寫檢查組件配置
如需在查詢中使用拼寫檢查,我們需要在solrconfig.xml中配置拼寫檢查組件,並在查詢請求處理器中配置使用拼寫檢查組件(往往作為最后一個組件)。
配置示例:
<searchComponent name="spellcheck" class="solr.SpellCheckComponent"> <!-- 如有需要,可為拼寫檢查指定單獨的分詞器(通過fieldType指定) --> <str name="queryAnalyzerFieldType">text_general</str> <!-- 在該組件中可定義多個拼寫檢查器(字典)--> <!-- a spellchecker built from a field of the main index --> <lst name="spellchecker"> <str name="name">default</str> <str name="field">text</str> <str name="classname">solr.DirectSolrSpellChecker</str> ... </lst> <!-- a spellchecker that can break or combine words. --> <lst name="spellchecker"> <str name="name">wordbreak</str> <str name="classname">solr.WordBreakSolrSpellChecker</str> <str name="field">name</str> ... </lst> </searchComponent>
說明:
1.一個拼寫檢查器就是一種拼寫檢查實現方式。由name、classname、field、其他參數構成。
2. 在一個組件中可定義拼寫檢查器(字典),供查詢處理器選擇使用(可同時選擇多個,推薦結果為多個的執行結果的合並)。
1.3 Solr中提供的拼寫檢查實現類
IndexBasedSpellChecker 獨立拼寫檢查索引的實現方式
DirectSolrSpellChecker 使用solr主索引進行拼寫檢查
FileBasedSpellChecker 通過文件來提供拼寫檢查推薦詞的實現方式
WordBreakSolrSpellChecker 可靈活拆分、組合詞,基於主索引的實現方式。如多個英文單詞少了空格的情況:solrspell checker,它可以進行拆分、組合嘗試來推薦詞。
DirectSolrSpellChecker配置參數說明
<lst name="spellchecker"> <str name="name">default</str> <!-- 通過查詢哪個字段的詞項來提供推薦詞 --> <str name="field">text</str> <str name="classname">solr.DirectSolrSpellChecker</str> <!-- 使用的拼寫檢查度量方法, 默認值internal 使用的是 levenshtein距離算法--> <str name="distanceMeasure">internal</str> <!-- 一個詞被認定為推薦詞需滿足的最低精確度。 0-1之間的浮點數,值越大精確度越高,推薦的詞越少 --> <float name="accuracy">0.5</float> <!-- 允許的最大編輯數(即最多多少個字符不同),可取值:1、2. --> <int name="maxEdits">2</int> <!-- 枚舉詞項來推薦時,要求的最低相同前綴字符數。--> <int name="minPrefix">1</int> <!-- 返回的最大推薦詞數。默認5 --> <int name="maxInspections">5</int> <!-- 要求的查詢詞項的最低字符數,默認4. 查詢的詞的字符數小於這個數就不進行拼寫檢查推薦。--> <int name="minQueryLength">4</int> <!-- 最大文檔頻率,高於該值的查詢詞不進行拼寫檢查的。可以是百分比或絕對值 --> <float name="maxQueryFrequency">0.01</float> <!-- 要求推薦詞的文檔頻率高於這個值。可以是百分比或絕對值 <float name="thresholdTokenFrequency">.01</float> --> </lst>
1.4 在查詢請求處理器中配置使用拼寫檢查
<requestHandler name="/spell" class="solr.SearchHandler" startup="lazy"> <!-- 拼寫檢查請求參數的默認值配置。--> <lst name="defaults"> <str name="spellcheck.dictionary">default</str> <str name="spellcheck.dictionary">wordbreak</str> <str name="spellcheck">on</str> <str name="spellcheck.extendedResults">true</str> <str name="spellcheck.count">10</str> <str name="spellcheck.alternativeTermCount">5</str> <str name="spellcheck.maxResultsForSuggest">5</str> <str name="spellcheck.collate">true</str> <str name="spellcheck.collateExtendedResults">true</str> <str name="spellcheck.maxCollationTries">10</str> <str name="spellcheck.maxCollations">5</str> </lst> <!-- 將拼寫檢查組件加到最后--> <arr name="last-components"> <str>spellcheck</str> </arr> </requestHandler>
拼寫檢查請求參數說明:
spellcheck:是否使用拼寫檢查,true/false
spellcheck.q:進行拼寫檢查的查詢表達式,如未指定則使用q。
spellcheck.count:返回最多多少個推薦詞。默認1。
spellcheck.dictionary:指定使用的拼寫檢查器(字典)名,默認default,同時使用多個則多次傳參指定。
spellcheck.accuracy:一個詞被認定為推薦詞需滿足的最低精確度。0-1之間的浮點數,值越大精確度越高,推薦的詞越少 spellcheck.onlyMorePopular:如果設置為true,只返回比原始查詢詞文檔頻率更高的推薦詞。
spellcheck.maxResultsForSuggest:原始查詢匹配的文檔數低於多少時才應該進行推薦,這個參數指定這個閥值。
spellcheck.extendedResults:true,獲取推薦詞的其他信息,如文檔頻次。
spellcheck.collate:true、指示solr為原始查詢生成一個最佳的校對查詢供用戶使用。如輸入“jawa class lording”,校對推薦"java class loading“
spellcheck.maxCollations:最多生成多少個校對查詢。默認1
spellcheck.build:true,則solr會為拼寫檢查建立字典(如未建立)。directSolrSpellCheck不需要此選項。
spellcheck.reload:是否重新加載spellchecker(以重新加載拼寫檢查字典)
1.5 拼寫檢查請求示例
嘗試下面的查詢請求,請看推薦結果在哪里,都有些什么推薦詞。
http://localhost:8983/solr/techproducts/spell?df=text&spellcheck.q=delll+ultra+sharp&spellcheck=true&spellcheck.collateParam.q.op=AND&wt=xml
2. 自動建議查詢詞
拼寫檢查是查詢后推薦,自動建議查詢詞則在用戶輸入查詢詞就根據用戶的輸入給出建議查詢詞,從最開始就避免拼寫錯誤,提供更好的用戶體驗,特別是在在移動設備上。
2.1 自動建議查詢詞組件
Solr中可以基於拼寫檢查組件實現自動建議查詢詞。也提供了專門的建議查詢詞組件solr.SuggestComponent。在techproducts示例的內核配置文件solrconfig.xml中配置有建議查詢詞組件和請求處理器,可直接參考。
自動建議查詢詞組件配置-示例
<searchComponent name="suggest" class="solr.SuggestComponent"> <!-- 可以定義多個建議器 --> <lst name="suggester"> <!-- 建議器名稱 --> <str name="name">mySuggester</str> <!-- 建議字典的查找實現類,默認 JaspellLookupFactory --> <str name="lookupImpl">FuzzyLookupFactory</str> <!-- 建議字典的實現類,默認 HighFrequencyDictionaryFactory --> <str name="dictionaryImpl">DocumentDictionaryFactory</str> <!-- 基於哪個字段來提供建議查詢詞 --> <str name="field">cat</str> <!-- 指定權重字段 --> <str name="weightField">price</str> <!-- 指定要使用的分詞器(通過fieldType) <str name="suggestAnalyzerFieldType">string</str> <!-- 是否在solr啟動時就構建字典 --> <str name="buildOnStartup">false</str> </lst> </searchComponent>
詳細參數、參數選項請參考:http://lucene.apache.org/solr/guide/7_3/suggester.html
自動建議查詢請求處理器配置-示例
<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>suggester</str> </arr> </requestHandler>
建議查詢詞請求參數說明:
suggest :是否使用建議查詢詞,true/false
suggest.q:進行建議查詢詞用的查詢表達式。
suggest.count:返回最多多少個推薦詞。
suggest.dictionary:指定使用的建議器(字典)名,必需。
suggest.build:true,構建建議字典索引,在初次請求時構建,后續請求不需要帶這個參數。
suggest.reload:是否重新加載建議查詢詞索引。
2.2 自動建議查詢請求-示例
http://localhost:8983/solr/techproducts/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=elec
使用多重suggest.dictionary:
http://localhost:8983/solr/techproducts/suggest?suggest=true&suggest.dictionary=mySuggester&suggest.dictionary=altSuggester&suggest.q=elec
四、折疊展開結果
1. 什么是折疊展開結果?
問:在商品搜索中,當我們輸入關鍵字,搜索到很多相關的商品文檔,當結果中存在大量的同名商品時(不同賣家的),你是希望看到重復的商品羅列還是看到更多的不同商品(同名商品展示一個)?
折疊結果:就是對搜索結果根據某字段的值進行分組去重。
展開結果:在返回結果中附帶上折疊結果的展開列表
請看下面查詢的結果:
http://localhost:8983/solr/techproducts/select?q=*:*&fq={!collapse%20field=price}&expand=true
2. Solr折疊展開結果
Solr中通過Collapsing query parser 和 Expand component 的組合來提供根據某一字段對搜索結果進行折疊、展開處理。Solr中還提供的結果分組組件也能實現折疊功能,但如果僅是要做折疊展開處理,折疊展開結果性能要優些。
CollapsingQParser 其實是一個后置查詢過濾器,對搜索結果根據指定的字段進行折疊處理。它需要的本地參數有:
field:指定折疊字段,必須是單值的String 、int 、float 類型的字段。
min or max:通過min或max指定的數值字段或函數查詢來選擇每個組的頭文檔(取最大或最小值的文檔)。min、max、sort只可用其一。
sort:指定組內排序規則來選擇排在第一的文檔作為頭文檔。默認是選取組中相關性評分最高的文檔作為頭文檔。
nullPolicy:對不包含折疊字段的文檔采取什么處理策略:
ignore:忽略,默認選項。
expand:獨立為一個組。
collapse:折疊為一個組。
折疊結果示例:
fq={!collapse field=group_field}
fq={!collapse field=group_field min=numeric_field}
fq={!collapse field=group_field max=numeric_field}
fq={!collapse field=group_field max=sum(cscore(),numeric_field)}
fq={!collapse field=group_field nullPolicy=collapse sort='numeric_field asc, score desc'}
2.1 Solr展開結果
如果你需要在結果中返回每個折疊組的展開列表,在請求中加上參數 expand=true
q=*:*&fq={!collapse%20field=price}&expand=true
展開組件還支持如下參數:
expand.sort:組內排序規則,默認是相關性評分。
expand.rows:每組返回的文檔數。默認5
還有 expand.q、expand.fq
五、結果分組
1. Solr結果分組
根據某個字段對結果進行分組,每組返回一個頭文檔。
http://localhost:8983/solr/techproducts/select?fl=id,name&q=solr+memory&group=true&group.field=manu_exact
結果分組請求參數說明:
group :true,對搜索結果進行分組。
group.field :分組字段,必須是單值、索引的字段。
group.func:根據函數查詢結果值進行分組(分布式下不可用)。
group.query:指定分組的查詢語句,類似 facet.query。
rows:返回的分組數,默認10
start:分頁起始行
group.limit:每組返回的文檔數,默認1。
group.offset:組內返回的文檔的偏移量。
sort:如何排序組。
group.sort:組內排序規則
group.main:用分組結果中的文檔作為主結果返回
2. Solr結果分組-示例
2.1 Grouping Results by Field 根據字段進行分組
http://localhost:8983/solr/techproducts/select?fl=id,name&q=solr+memory&group=true&group.field=manu_exact
作為主結果返回
http://localhost:8983/solr/techproducts/select?fl=id,name,manufacturer&q=solr+memory&group=true&group.field=manu_exact&group.main=true
2.2 Grouping by Query 根據查詢進行分組
http://localhost:8983/solr/techproducts/select?indent=true&fl=name,price&q=memory&group=true&group.query=price:[0+TO+99.99]&group.query=price:[100+TO+*]&group.limit=3
六、其他搜索特性介紹
1. Result clustering 結果聚合
http://lucene.apache.org/solr/guide/7_3/result-clustering.html
2. Spatial Search 地理空間搜索
http://lucene.apache.org/solr/guide/7_3/spatial-search.html
3. Parallel SQL Interface 搜索的SQL接口
http://lucene.apache.org/solr/guide/7_3/parallel-sql-interface.html