Solr之查詢索引。
Solr在不修改任務配置的情況下就可以使用查詢功能,在web專案中應用可以直接URL進行訪問Solr伺服器例如:
http://localhost:8080/solr/collection1/select?q=*%3A*&wt=xml&indent=true
上面的意思就是查詢名為collection1的SolrCore的所有內容用xml格式返回並且有縮排,返回結果如下:
<?xml version = "1.0" encoding = "UTF-8" ?>
<response>
<lst name = "responseHeader">
<int name = "status">0</int>
<int name = "QTime">0</int>
<lst name = "params">
<str name = "indent">true</str>
<str name = "q">*.*</str>
<str name = "wt">xml</str>
</lst>
</lst>
<result name = "response" numFound = "17971" start = "0">
<doc>
<str name = "path">E:\Reduced\軍事\1539.txx</str>
<str name = "category_s">2</str>
<int name = "browseCount_i">1423701734</int>
<long name = "modified_l">1162438568000</long>
<long name = "releasedate_l">1162438568000</long>
<str name = "content"> [俄羅斯lenta網站2006年2月9日報道]俄空軍副總司令比熱耶夫中將稱,2006年春天獨聯體國家防空系統打擊範圍向西推進150千米,偵察範圍向西推進400千米。 2006年3月白俄羅斯4個S-300PS防空導彈營擔負戰鬥任務,使獨聯體防空系統作戰範圍得以向西推進。比熱耶夫中將還宣佈,近期烏茲別克可能加入獨聯體防空系統。 獨聯體國家防空系統建於9年前,共有9個國家參加該組織。目前只有亞美尼亞、白俄羅斯、哈薩克、吉爾吉斯、俄羅斯和塔吉克支援該體系。 烏克蘭、烏茲別克與俄羅斯在雙邊基礎上合作,喬治亞和土庫曼最近7年不參加獨聯體國家對空防禦。</str>
<str name = "id">E3798D82-EAB6-2BEA-D7E2-79FBD102E845</str>
<long name = "_version_">1436361868021071872</long>
</doc>
...
</result>
</response>
上面所看到的就是用xml格式返回的查詢結果,其中的doc就是一個文件,在doc裡面的那個就是我們開始在schema.xml中定義的欄位。
如果使用SolrJ進行呼叫的話程式碼如下:
SolrQuery query = new SolrQuery();
query.set("q" , "*.*");
QueryResponse rsp = server.query(query);
SolrDocumentList list = rsp.getResults();
返回結果在SolrDocumentList中在這個物件中遍歷取出值來:
for(int i = 0 ; i < list.size() ; i ++ ) {
SolrDocument sd = list.get(i);
String id (String) sd.getFieldValue("id");
System.out.printlnl(id);
}
查詢引數
名稱 描述 q 查詢字串,必須的。 fq filter query。使用Filter Query可以充分利用Filter Query Cache,提高檢索效能。作用:在q查詢符合結果中同時是fq查詢符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找關鍵字mm,並且date_time是20081001到20091031之間的。 fl field list。指定返回結果欄位。以空格“”或逗號“,”分隔。 start 用於分頁定義結果起始記錄數,預設為0. rows 用於分頁定義結果每頁返回記錄數,預設為10. sort 排序,格式:sort=<fieldname> + <desc|asc>[<fieldname> + <desc|asc>]。示例,(inStock desc , price asc) 表示先“inStock”降序,再“price”升序,預設是相關性降序。 df 預設的查詢欄位,一般預設指定。 q.op 覆蓋schema.xml的defaultOperator(有空格時用“AND”還是用“OR”操作邏輯),一般預設指定。必須大寫。 wt writer type。指定查詢使用輸出結構格式,預設為“xml”。 qt query type,指定查詢使用的Query Handler,預設為“standard”。 explainOther 設定當debugQuery=true時,顯示其他的查詢說明。 defType 設定查詢解析器名稱。 timeAllowed 設定查詢超時時間。 omitHeader 設定是否忽略查詢結果返回頭資訊,預設為“false”。 indent 返回的結果是否縮排,預設關閉,用indent=true|on開啟,一般除錯json,php,phps,ruby輸出才有必要用這個引數。 version 查詢語法的版本,建議不使用它,由伺服器指定預設值。 debugQuery 設定返回結果是否顯示Debug資訊。
查詢語法
- 匹配所有文件:*:*。
- 強制、阻止和可選查詢:
- Mandatory:查詢結果中必須包括的(for example,only entry name containing the word make)
Solr/Lucene Statement:+make,+make+up,+make+up+kiss
- prohibited:(for example,all documents except those with word belive)
Solr/Lucene Statement:+make +up -kiss
- optional:
Solr/Lucene Statement:+make +up kiss
- 布林操作:AND、OR和NOT布林操作(必須大寫)與Mandatory、optional和prohibited相似。
- make AND up = +make + up: AND 左右兩邊的操作都是mandatory。
- make || up = make OR up = make up : OR 左右兩邊的操作都是 optional。
- +make +up NOT kiss = +make +up -kiss
- make AND up OR french AND Kiss 不可以達到期望的結果,因為AND兩邊的操作都是mandatory的。
- 子表示式查詢(子查詢):可以使用“0”構造子查詢。
示例:(make AND up) OR (french AND Kiss)
- 子表示式查詢中阻止查詢的限制:
示例:make( -up) :只能取得make的查詢結果;要使用make (-up *:*)查詢make或者不包括up的結果。
- 多欄位fields查詢:通過欄位名加上分號的方式(fieldName:query)來進行查詢。
示例:entryNm:make AND entryId:3cdc86e8e0fb4da8ab17caed42f6760c
- 萬用字元查詢(wildCard Query):
- 萬用字元 ? 和 * :“*”表示匹配任意字元;“?”表示匹配出現的位置。
示例:ma?*(ma後面的一個位置匹配),ma??*(ma後面兩個位置都匹配)
- 查詢字元必須要小寫:+Ma +be**可以搜尋到結果;+Ma +Be**沒有搜尋結果。
- 查詢速度較慢,尤其是萬用字元在首位:主要原因一是需要迭代查詢欄位中的每個term,判斷是否匹配;二十匹配上的term被加到內部的查詢,當terms數量達到1024的時候,查詢會失敗。
- Solr中預設萬用字元不能出現在首位(可以修改QueryParser,設定setAllowLeadingWildcard為true)。
- 設定setAllowLeadingWildcard為true。
- 模糊查詢、相似查詢:不是精確地查詢,通過對查詢的欄位進行重新插入、刪除和轉換來取得得分較高的查詢解決(由Levenstein Distance Algorithm演算法支援)。
- 一般模糊查詢:示例,make-believ~
- 門檻模糊查詢:對模糊查詢可以設定查詢門檻,門檻是0~1之間的數值,門檻越高表面相似度越高。示例,make-believ~0.5、make-believ~0.8、make-believ~0.9。
- 範圍查詢(Range Query):Lucene支援對數字、日期甚至文字的範圍查詢。結束的範圍可以使用“*”萬用字元。
示例:
- 日期範圍(ISO-8601 時間GMT):sa_type:2 AND a_begin_date:[1990-01-01T00:00:00.000Z TO 1999-12-31T24:59:99.999Z]
- 數字:salary:[2000 TO *]
- 文字:entryNm:[a TO a]
- 日期匹配:YEAR,MONTH,DAY,DATE(synonymous with DAY) HOUR,MINUTE,SECOND,MILLISECOND,and MILLI(synonymous with MILLISECOND)可以被標誌成日期。
示例:
- r_event_date:[* TO NOW-2YEAR]:2年前的現在這個時間。
- r_event_date:[* TO NOW/DAY-2YEAR]:2年前前一天的這個時間。
函式查詢(Function Query)
函式查詢,可以利用numeric欄位的值或者與欄位相關的某個特定的值得函式,來對文件進行評分。
使用函式查詢的方法
這裡主要有三種方法可以使用函式查詢,這三種方法都是通過solr http介面的。
- 使用FunctionQParserPlugin。ie:q={!func}log(foo)
- 使用“_val_”內嵌方法。
內嵌在正常的solr查詢表示式中。即,將函式查詢寫在 q 這個引數中,這時候,我們使用“_val_”將函式與其他的查詢加以區別。
ie: netryName:make && _val_:ord(entryNm)
- 使用dismax中的bf引數。
使用明確為函式查詢的引數,比如說dismax中的bf(boost function)這個引數。注意:bf這個引數可以接受多個函式查詢的,他們之間用空格隔開,他們還可以帶上權重。所以,當我們使用bf這個引數的時候,我們必須保證單個函式中是沒有空格出現的,不然程式有可能會以為是兩個函式。
示例:
q=dismax&bf="ord(proularity)^0.5 recip(rord(price),1,1000,1000)^0.3"
函式的格式(Function Query Syntax)
目前,function query 並不支援 a+b這樣的形式,我們得把他寫成一個方法形式,這就是sum(a,b)。
使用函式查詢注意事項
- 用於函式查詢的field必須是被索引的;
- 欄位不可以是多值(multi-value)。
可以利用的函式(avaliable function)
- constant:支援有小數點的常量;例如:1.5;SolrQuerySyntax:_val_:1.5
- fieldvale:這個函式將會返回numeric field的值,這個欄位必須是indexed的,非multiValued的。格式很簡單,就是該欄位的名字。如果這個欄位中沒有這樣的值,那麼將會返回0.
- ord:對於一個欄位,它所有的值都將會按照字典順序排列,這個函式返回你要查詢的那個特定的值在這個順序中的排名。這個欄位,必須是非multiValued的,當沒有值存在的時候,將返回0.例如:某個特定的欄位只能去三個值,“apple”、“banana”、“pear”,那麼ord("apple")=1,ord("banana")=2,ord("pear")=3,需要注意的是,ord()這個函式,依賴於值在索引中的位置,所以當有文件被刪除或者新增的時候,ord()的值就會發生變化。當你使用MultiSearcher的時候,這個值也就是不定的了。
- rord:這個函式將會返回與ord相對應的倒排序的排名。
格式:rord(myIndexedField)。
- sum:這個函式的意思就顯而易見,他就是表示“和”。
格式:sum(x , 1)、 sum(x , y)、sum(sqrt(x) , log(y) , z , 0.5)
- product:product(x , y , ...) 將會返回多個函式的乘積。
格式:product(x , 2) 、product(x , y)
- div:div(x , y)表示x除以y的值。
格式:div(1 , x) 、 div(sum(x , 100) , max (y , 1))
- pow:pow表示冪值。
pow(x , y) = x ^ y。例如:pow(x , 0.5) 表示開方 pow(x , log(y))。
- abs:abs(x)將返回表示式的絕對值。
格式:abs(-5)、abs(x)
- log:log(x)將會返回基數為10,x的對數。
格式:log(x)、log(sum(x , 100))
- Sqrt:sqrt(x)返回一個數的平方根。
格式:sqrt(2)、sqrt(sum(x , 100))
- Map:如果x >= min,且 x <= max,那麼map(x,min,max,target) = target;如果x不再[min , max] 這個區間內,那麼map(x , min , max ,target) = x。
格式:map(x , 0 , 0 , 1)
- Scale:scale(x , minTarget , maxTarget) 這個函式將會把x的值限制在[minTarget , maxTarget]範圍內。
- query:query(subquery , default)將會返回給定subquery的分數,如果subquery與文件不匹配,那麼將會返回預設值。任何的查詢型別都是受支援的。可以通過應用的方式,也可以直接指定查詢串。
示例:q = product(popularity , query({!dismax v = 'solr rocks'})) 將會返回popularity和通過dismax查詢得到的分數的乘積。
q = product(popularity , query($qq)&qq={!dismax} solr rocks)跟上一個例子的效果是一樣的。不過這裡使用的是引用的方式。
q = product(popularity , query($qq , 0.1))&qq ={!dismax} solr rocks)在前一個例子的基礎上又加了一個預設值。
- linear:linear(x , m , c) 表示m*x+c,其中m和c都是常量,x是一個變數也可以是一個函式。
例如:linear(x , 2 , 4) = 2*x+4。
- Recip:recip(x , m , a , b) = a/(m*x+b),其中,m、a、b是常量,x是變數或者一個函式。當a=b並且x>=0的時候,這個函式的最大值是1,值得大小隨著x的增長而減小。
例如:recip(rord(creationDate) , 1 , 1000 , 1000)。
- Max:max(x , c)將會返回一個函式和一個常量之間的最大值。
例如:max(myfield , 0)