搜索引擎(Solr-搜索詳解)

學習目標

1.掌握SOLR的搜索工做流程;
2.掌握solr搜索的表示語法及查詢解析器
3.熟悉solr搜索的JSON格式 APIhtml

Solr搜索流程介紹

回顧,使用 lucene進行搜索的步驟:java

Solr搜索的工做流程web

查看內核的solrconfig.xml文件,瞭解搜索的請求處理器配置express

對比看_default、sample_techproducts_configs兩種配置集的內核配置。apache

配置中的參數元素介紹見下一頁。json

仔細查看techproducts 內核的solrconfig.xml的
/select
/query
/browse緩存

前面流程圖中的各項工做都在哪裏完成?
在SearchHandler
它是如何完成的?app

參數元素說明less

SearchHandler介紹electron

查詢請求在SearcheHandler這個request handler中完成,各個步驟的工做由SearchHandler中組合的組件來完成了(可自定義,在該查詢的requesthandler配置元素內配置)。示例,自定義組件組合:

<arr name="components">
 <str>query</str>
 <str>facet</str>
 <str>mlt</str>
 <str>highlight</str>
 <str>debug</str>
 <str>someothercomponent</str>
</arr>

"query" (usually QueryComponent)
"facet" (usually FacetComponent)
"mlt" (usually MoreLikeThisComponent)
"highlight" (usually HighlightComponent)
"stats" (usually StatsComponent)
"debug" (usually DebugComponent)

還可在主組件組合前、後加入組件:

<arr name="first-components">
  <str>mycomponent</str>
</arr>
<arr name="last-components">
  <str>myothercomponent</str>
</arr>

詳細瞭解: https://wiki.apache.org/solr/SearchHandler

問:SearchHandler中配置的 default是作什麼用的?

默認參數設置,若是你有這樣的默認查詢參數須要,可這樣配置。

查詢語法及解析器詳解

通用查詢參數詳解

1.defType
defType用來選擇解析參數q指定的主查詢串的查詢解析器,如未給定默認使用solr的標準查詢解析器(defType=lucene)。
Solr中提供了三種解析器供選擇:
lucene:   solr的Standard Query Parser  標準查詢解析器
dismax:   DisMax Query Parser
edismax: Extended DisMax Query Parser (eDismax)

2.sort
指定如何對搜索結果進行排序,asc 表示聖墟,desc 降序。Solr可根據以下部分對結果文檔進行排序:
文檔相關性得分
函數計算的結果
設置了docValues="true"的基本數據類型字段(numerics, string, boolean, dates, etc.) 
存儲了docValues的可排序分詞索引字段(SortableTextFields)。
單值不分詞索引的字段。
對於基本數據類型和SortableTextFields ,若是是多值的,排序規則:
升序:取最小值參與排序;
降序:取最大值進行排序;
如要指定用什麼值:則在傳參時用sort=field(name,max) or sort=field(name,min) 方式傳參。

3.start
分頁查詢的起始行號(從0開始),沒傳默認爲0。

4.rows
查詢返回多少行,默認10(可配置)。

5.fq
Filter Query 用來在主查詢的結果上進行過濾,不影響相關性評分。Fq對於提速複雜的查詢很是有用。由於fq指定的過濾查詢結果是獨立於主查詢被緩存起來的。對於下次查詢,若是用到了該過濾查詢,則直接從緩存中取出結果進行對主查詢的結果進行過濾便可。

fq的傳參說明:
能夠一次傳傳多個fq:
	fq=popularity:[10 TO *]&fq=section:0
也可將多個過濾條件組合在一個fq:
	fq=+popularity:[10 TO *] +section:0

說明:幾個fq就緩存幾個過濾結果集

6.fl
fl(field list),指定結果中返回哪些字段,指定的字段必須是 stored="true" or docValues="true" 的。多個字段用空格或英文逗號間隔。須要評分時經過 score 指定。若是傳人的值爲*,則stored="true" or docValues="true" and useDocValuesAsStored="true"的字段都會返回。

7.debug
debug參數用於指定在結果中返回調試信息。

8.explainOther
在一個查詢中附帶解釋另外一個查詢的評分,在結果中返回它的得分解釋。這可讓咱們在topN查詢時理解爲何某個文檔沒有返回。
示例:
	q=supervillians&debugQuery=on&explainOther=id:juggernaut

9.timeAllowed
限定查詢在多少毫秒內返回,若是到時間了還未執行完成,則直接返回部分結果。

10.omitHeader
true/false ,如設爲true,在則響應體中忽略表示查詢執行狀態信息(如耗時)的頭。

11.wt
指定響應的內容格式:json、xml、csv……  SearchHandler根據它選擇ResponseWriter。

12.cache
設置是否對查詢結果、過濾查詢的結果進行緩存。默認是都會被緩存的。若是不須要緩存明確設置 cache=false。

13.logParamsList
solr默認會日誌記錄全部的請求參數,若是不須要記錄全部,則經過此參數指定要記錄的參數名,如:
	logParamsList=q,fq
若是都不記錄:傳入: logParamsList=

14.echoParams
指定在響應體的內容的頭部中返回哪些查詢參數,可選值:
explicit: 默認,返回顯示傳入的參數+
all: 應用到查詢的全部參數.
none:不返回.

查詢解析器介紹

Standard Query Parser
DisMax Query Parser
Extended DisMax Query parser

默認使用的是 Standard Query Parser 。經過defType參數可指定。

Standard Query Parser

solr標準查詢解析器。關鍵優勢:它支持一個健壯且至關直觀的語法,容許咱們建立各類結構的查詢。這個咱們在學習lucene時已學過。最大的缺點:它不能容忍語法錯誤。

Standard Query Parser  請求參數

除了通用參數外,標準查詢解析器還支持的參數有:

q:用標準查詢語法定義的查詢表達式(查詢串、主查詢),必需。
q.op:指定查詢表達式的默認操做, 「AND」 or 「OR」,覆蓋默認配置值。
df:指定默認查詢字段
sow: Split on whitespace 按空格分割,若是設置爲true,則會分別對分割出的文本進行分詞處理。默認false。

Standard Query Parser  響應內容格式

請求:http://localhost:8983/solr/techproducts/select?q=id:SP2514N&wt=xml

Standard Query Parser  響應內容格式-練習

一、加上debug=all參數看看返回什麼.

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=xml&debug=all

二、加上explainOther參數看看返回什麼

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=xml&debug=all&explainOther=id:055357342X

三、把wt改成json看看與xml的不一樣

http://localhost:8983/solr/techproducts/select?q=cat:book&wt=json&debug=all&explainOther=id:055357342X

標準查詢語法:

Term 詞項表示:

單個詞項的表示:     電腦
短語的表示:     "聯想筆記本電腦"

Field 字段:

字段名:
示例: name:「聯想筆記本電腦」 AND type:電腦
若是name是默認字段,則可寫成: 「聯想筆記本電腦」 AND type:電腦
若是查詢串是:type:電腦 計算機 手機
注意:只有第一個是type的值,後兩個則是使用默認字段。

Term Modifiers 詞項修飾符:

範圍查詢:

    mod_date:[20020101 TO 20030101]       包含邊界值
    title:{Aida TO Carmen}      不包含邊界值

詞項加權,使該詞項的相關性更高,經過 ^數值來指定加權因子,默認加權因子值是1

示例:如要搜索包含 jakarta apache 的文章,jakarta更相關,則: jakarta^4 apache 短語也能夠: "jakarta apache"^4 "Apache Lucene"

^=  固定分值,經過此字句匹配的文檔使用固定的分值。

(description:blue OR color:blue)^=1.0 text:shoes

Boolean 操做符

組合 () 

字句組合    (jakarta OR apache) AND website

字段組合    title:(+return +"pink panther")

轉義   \

對語法字符: + - && || ! ( ) { } [ ] ^ 「 ~ * ? : \ /     進行轉義。 如要查詢包含 (1+1):2        \(1\+1\)\:2

註釋,支持C語言風格的註釋

"jakarta apache" /* this is a comment in the middle of a normal query string */ OR jakarta

Solr Standard Query Parser 對傳統 lucene語法的加強

在範圍查詢的邊界兩端均可以用*

field:[* TO 100] finds all field values less than or equal to 100
field:[100 TO *] finds all field values greater than or equal to 100
field:[* TO *] matches all documents with the field

容許純非的查詢(限頂級字節)

-inStock:false   finds all field values where inStock is not false
-field:[* TO *]   finds all documents without a value for field

支持嵌入solr查詢(子查詢),切入查詢可使用任意的solr查詢解析器

inStock:true OR {!dismax qf='name manu' v='ipod'}

支持特殊的filter(…) 語法來講明某個字句的結果要做爲過濾查詢進行緩存

q=features:songs OR filter(inStock:true)
q=+manu:Apple +filter(inStock:true)
q=+manu:Apple & fq=inStock:true

若是過濾查詢中的某個字句須要獨立進行過濾緩存,也可用。

q=features:songs & fq=+filter(inStock:true) +filter(price:[* TO 100])
q=manu:Apple & fq=-filter(inStock:true) -filter(price:[* TO 100])

範圍查詢 (「[a TO z]」), 前綴查詢 (「a*」), 統配符查詢(「a*b」)  使用規定分值。

查詢中的時間表示語法,遵照前面講索引時的規範

createdate:1976-03-06T23\:59\:59.999Z
createdate:"1976-03-06T23:59:59.999Z"
createdate:[1976-03-06T23:59:59.999Z TO *]
createdate:[1995-12-31T23:59:59.999Z TO 2007-03-06T00:00:00Z]
timestamp:[* TO NOW]
pubdate:[NOW-1YEAR/DAY TO NOW/DAY+1DAY]
createdate:[1976-03-06T23:59:59.999Z TO 1976-03-06T23:59:59.999Z+1YEAR]
createdate:[1976-03-06T23:59:59.999Z/YEAR TO 1976-03-06T23:59:59.999Z]

DisMax Query Parser

DisMax Query Parser 是設計用於處理用戶輸入的簡單短語查詢的,它的特色:

1 只支持查詢語法的一個很小的子集:簡單的短語查詢、+  - 修飾符、AND OR 布爾操做; 
2 簡單的語法,不拋出語法錯誤異常給用戶。 
3 能夠在多個字段上進行短語查詢。
4 能夠靈活設置各個查詢字段的相關性權重。
5 能夠靈活增長知足某特定查詢文檔的相關性權重。

DisMax:Maximum Disjunction  最大分離。

DisMax Query 定義:一個查詢,能夠爲不一樣字段設置評分權重,在合併它的查詢字句的命中文檔時,每一個文檔的分值取各個字句中的最大得分值。

DisMax Query Parser參數說明

1.2查詢參數說明
1.2.1q
指定主查詢表達式。注意簡單短語,不可以使用通配符,+號會被當成或處理。

1.2.2q.alt
q.alt 提供一個備選語句,當q沒有指定或爲空時,執行這個查詢。

1.2.3qf
qf指定要查詢的字段及權重。
qf="fieldOne^2.3 fieldTwo fieldThree^0.4"


1.2.4mm (Minimum Should Match)
mm 用來指定當q中包含多個字句、各字句是或操做時,最少需多少個字句匹配纔算匹配。mm支持很是靈活的表示方式:

mm的默認值是100%。

1.2.5pf (Phrase Fields) 
pf用來設置當某個字段匹配全部查詢字句的短語時,該字段的加權權重。定義格式同qf
pf="fieldOne^2.3 fieldTwo fieldThree^0.4"

1.2.6ps (Phrase Slop)
短語的移動因子。當查詢給入多個詞、短語時。對這些詞進行短語匹配的移動因子。

1.2.7qs (Query Phrase Slop) 
用戶給入的q 主查詢中包含短語時,經過qs可指定短語的移動因子。

1.2.8tie (Tie Breaker)
這個tie參數一般是一個小於1的浮點數,當查詢命中多個field的時候,最終的score得到多少將由這個tie參數來進行調節。好比命中了field1,field2這2個field。若是field1.score= 10,field2.score=3。那麼 score = 10 + tie * 3.也就是說,若是tie=1的話,最終的score就至關於多個字段得分總和;若是tie=0,那麼最終的score就至關因而命中的field的最高分。一般狀況下呢,官方推薦tie=0.1。


1.2.9bq (Boost Query)
bq指定一個加權查詢,當主查詢中命中的文檔符合bq加權查詢時,將得到更高的得分。
q=cheese
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]AND ^5.0 
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]^5.0
bq=date:[NOW/DAY-1YEAR TO NOW/DAY]^5.0
能夠指定多個bq參數。

1.2.10bf (Boost Functions) 
bf用來定義加權函數,而後可在bq中使用加權函數

bf=recip(rord(creationDate),1,1000,1000)
  ...or...
bq={!func}recip(rord(creationDate),1,1000,1000)


1.3DisMax Query Parser使用舉例
1.使用StandardRequestHandler查詢」video」 http://localhost:8983/solr/techproducts/select?q=video&fl=name+score
2.配置了查詢字段:text、features、name、id、manu、cat。並且匹配上name和cat會有更高的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video
3.能夠將score顯示出來,看一下各個文檔的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&fl=*,score
4.覆蓋查詢字段,並設置features有更高的得分,而text有較低的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&qf=features^20.0+text^0.3
5.但願某一字段在知足某一狀況下有更高的得分 http://localhost:8983/solr/techproducts/select?defType=dismax&q=video&bq=cat:electronics^5.0


Extended DisMax Query Parser

擴展 DisMax Query Parse 使支標準查詢語法(是 Standard Query Parser 和 DisMax Query Parser 的複合)。也增長了很多參數來改進disMax。
強烈建議:使用 edismax 來進行查詢解析:
       支持的語法很豐富;
       很好的容錯能力;
       靈活的加權評分設置。

請求參數說明

1.sow
sow:Split on whitespace 按空格拆分。若是設置爲true,則對每一個單獨的空格分隔的文本分別調用文本分析。默認是false;空格分隔的術語序列將一次性提供給文本分析,從而使分析篩選器的功能可以正常運行(如同義詞處理)。
2.mm.autoRelax
如設置爲true,當查詢表達式的字句經分詞過濾後在部分查詢字段上(而非所有)減小字句了,最少匹配數自動放鬆。此參數用於解決因停用詞過濾致使的查詢不到文檔的問題。

3.boost
加權函數查詢,符合該查詢的文檔的得分=主查詢得分 * 該加權查詢得分。注意這裏是乘。而 bq、bf是加
如根據各商品的熱度對命中的商品文檔加權
http://localhost:8983/solr/techproducts/select?defType=edismax&q=solr &pf=text&qf=text&boost=popularity

4.lowercaseOperators
true 支持 小寫的 and  or。
1.2.5ps (Phrase Slop)
做爲短語加權匹配時的移動因子,會做爲 ps2  ps3的默認值。
ps=5

6.pf2
指定要進行二元組短語加權的字段及權重,相似pf,不一樣之處:pf要求短語完整匹配,pf2是將查詢的詞分解爲二元組進行短語匹配來加權。如查詢的詞爲:solr based lucece java,pf2會對包含短語」solr based」或」based lucene」或」lucene java」的文檔加權。
q= solr based lucece java&pf2=title^10 content^3&ps2=3 

7.ps2
pf2使用的移動因子,如未給定則使用ps。

8.pf3
指定要進行三元組短語查詢加權的字段及權重。
如查詢的詞爲:solr based lucece java 會被分爲」 solr based lucece」、」 based lucece java」,在pf3指定的字段上進行短語匹配、加權。
q= solr based lucece java&pf3=title^10 content^3&ps3=2

9.ps3
pf3使用的移動因子,如未給定則使用ps。

10.stopwords
控制是否在查詢的分析器中開啓停用詞過濾,默認是true。

11.uf
指定容許用戶能夠查詢哪些字段以及開啓嵌入查詢支持,默認是全部字段、不可嵌入查詢: uf=* -_query_。uf值支持通配符,以空格間隔多個字段。
示例:
  To allow only title field, use uf=title.
  To allow title and all fields ending with '_s', use uf=title *_s.
  To allow all fields except title, use uf=* -title.
  To disallow all fielded searches, use uf=-*.
  To allow embedded Solr queries (e.g. _query_:"…​" or _val_:"…​" or {!lucene …​}), you must expressly enable this by referring to the magic field _query_ in uf

查詢字段別名

有時咱們在模式中定義的字段不適合直接給終端用戶使用,如動態字段、很長的字段名(對用戶使用不是很友好)。在eDismax中提供了查詢字段別名機制,對用戶更友好地寫查詢表達式,咱們在默認補充別名定義。如模式中的字段名爲: title_t_zh 但願以title 來給用戶用。咱們能夠經過 f.alias.qf=realField參數來定義別名。
示例:
defType=edismax&q=title:」lucene solr」&f.title.qf=title_t_zh

因是對查詢字段取別名,能夠更靈活的使用:
&f.who.qf=name^20 author^30&f.what.qf=cat^5 job^10
用戶在寫q時能夠這樣寫 q=who:(mike tony) what:(動腦)
defType=edismax&q=who:(mike tony) what:(動腦)&f.who.qf=name^20 author^30&f.what.qf=cat^5 job^10&debug=all

示例

根據文檔的流行度提高查詢詞 「hello」 的結果:
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod&pf=text&qf=text&boost=popularity

使用負的boost
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod&pf=text&qf=text&boost=sub(0,popularity)
搜索 iPod 或視頻:
http://localhost:8983/solr/techproducts/select?defType=edismax&q=ipod+OR+video
在多個字段中搜索,指定(經過 boosts)每一個字段相對於彼此的重要性:
http://localhost:8983/solr/techproducts/select?q=video&defType=edismax&qf=features^20.0+text^0.3
您能夠提升具備與特定值匹配的字段的結果:
http://localhost:8983/solr/techproducts/select?q=video&defType=edismax&qf=features^20.0+text^0.3&bq=cat:electronics^5.0
使用「mm」參數,1和2個單詞查詢要求全部可選子句匹配,但對於具備三個或更多子句的查詢,容許使用一個缺失子句:
http://localhost:8983/solr/techproducts/select?q=belkin+ipod&defType=edismax&mm=2
http://localhost:8983/solr/techproducts/select?q=belkin+ipod+gibberish&defType=edismax&mm=2
http://localhost:8983/solr/techproducts/select?q=belkin+ipod+apple&defType=edismax&mm=2
 

 

函數

solr查詢也可以使用函數,可用來過濾文檔、提升相關性值、根據函數計算結果進行排序、以及返回函數計算結果。在標準查詢解析器、dismax、edismax中均可以使用函數。

函數能夠是

常量:數值或字符串字面值,如 十、」lucene solr」
字段:  name  title
另外一個函數:functionName(…)
替代參數:
         q={!func}min($f1,$f2)&f1=sqrt(popularity)&f2=1

函數的使用方式有:

用做函數查詢,查詢參數值是一個函數表達式,來計算相關性得分或過濾

q={!func}div(popularity,price)&fq={!frange l=1000}customer_ratings

在排序中使用:

sort=div(popularity,price) desc, score desc

在結果中使用:

&fl=sum(x, y),id,a,b,c,score&wt=xml

在加權參數 bf、boost中使用來計算權重

q=dismax&bf="ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3"

在設置評分計算函數的特殊關鍵字 _val_ 中使用

q=_val_:mynumericfield    _val_:"recip(rord(myfield),1,2,3)"

Function Query 函數查詢說明:

函數查詢:指咱們在查詢參數q、fq中使用了函數來改變相關性得分或過濾的一類特殊查詢。函數對全部匹配的文檔分別進行計算獲得一個值做爲一個加分值,加入到文檔的相關性得分中。

改變評分:

方式一:整個查詢就是一個函數表達式,匹配全部文檔,文檔的得分就是函數值

q=*:*
q={!func}div(popularity,price)&debug=all

說明:{!func} 說明q參數須要用func查詢解析器來解析,func:Function Query Parser

方式二:值掛接,加入一個評分項,文檔的得分=其餘關鍵字得分 + 函數值

q=ipod AND _val_:"div(popularity,price)"&debug=all

方式三:查詢解析器掛接(顯示嵌套查詢)

q=ipod AND _query_:"{!func}div(popularity,price)"&debug=all

方式四:查詢解析器掛接(隱式嵌套查詢)

q=ipod AND {!func  v ="div(popularity,price)"}&debug=all

經過函數來過濾文檔:

若是須要對搜索結果進行過濾,只留下函數計算產生特定值的文檔,能夠選擇函數區間解析器(Function Range query parser,簡稱frange)。在q/fq參數中應用frange 執行一個特定的函數查詢,而後過濾掉函數值落在最低值和最高值範圍以外的文檔。

q={!frange l=0.01 u=0.1}div(popularity,price)&debug=all
q=ipod&fq={!frange l=0.05 u=0.1}div(popularity,price)&debug=all

Solr中提供的函數:

官網參考:https://lucene.apache.org/solr/guide/7_3/function-queries.html#product-function

​​​​​​1.數據轉換函數

 

2.數學函數

 

3.相關性函數

示例: doc1:(fieldX:A B C) and doc2:(fieldX:A A A A):
docFreq(fieldX:A) = 2 (A appears in 2 docs)
freq(doc1, fieldX:A) = 4 (A appears 4 times in doc 2)
totalTermFreq(fieldX:A) = 5 (A appears 5 times across all docs)
sumTotalTermFreq(fieldX) = 7 in fieldX, there are 5 As, 1 B, 1 C
利用函數查詢和相關性函數,咱們就能夠自定義相關性計算模型。

 

4.布爾函數

 

4.距離函數

 

​​​​​​​5.自定義函數

Solr中實現自定義函數很是簡單。步驟以下:
一、編寫一個函數類,這個類繼承ValueSource類,保證在搜索索引中的每一個文檔都返回一個計算值。
二、編寫ValueSourceParser類,它能夠理解自定義函數的語法(在該類中你編寫如何解析的邏輯),並將它解析成第1步自定義的ValueSource函數須要的變量。
三、向solrconfig.xml文件添加一個XML元素,定義自定義函數的名稱及ValueSourceParser的類。當自定義函數經過函數名調用時,ValueSourceParser類將會解析ValuesSource中的輸入。

 

什麼是本地參數?

做爲查詢參數值的前綴,用來爲查詢參數添加元數聽說明用的參數。看下面的查詢:

q=solr rocks

如須要爲這個查詢說明是進行 AND 組合及默認查詢字段是title:

q={!q.op=AND df=title}solr rocks

本地參數語法

做爲查詢參數值的前綴,用 {!key=value key=value} 包裹的多個key=value

本地參數用法示例

Query Type 的簡寫形式,type指定查詢解析器

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield}solr rocks

經過v 關鍵字指定參數值

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield v='solr rocks'}

參數引用

q={!dismax qf=myfield}solr rocks
q={!type=dismax qf=myfield v=$qq}&qq=solr rocks

其餘查詢解析器

其餘查詢解析器,讓咱們能夠在查詢中靈活根據須要以本地參數的方式選用。

請參考官網: https://lucene.apache.org/solr/guide/7_3/other-parsers.html

 

小結

如何來寫一個查詢?  掌握語法 q 如何指定查詢字段?  Field:    df    qf  如何添加過濾條件?Fq     {!frange} 如何指定返回字段? fl 如何指定排序? sort 如何爲某個詞項、短語加權?詞項、短語^5 如何爲字段加權? qf=title^10   pf   pf2  pf3 如何用字段值來進行加權,如流行度、銷量? _val_   _query_  函數查詢 如何查看某個查詢的調試信息? debug  

相關文章
相關標籤/搜索