1. 程式人生 > >Solr之查詢索引。

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)