solr的查詢語法
一.基本查詢
q – 查詢字符串,必須的。
fl – 指定返回那些字段內容,用逗號或空格分隔多個。
start – 返回第一條記錄在完整找到結果中的偏移位置,0開始,一般分頁用。
rows – 指定返回結果最多有多少條記錄,配合start來實現分頁。
sort – 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:(inStock desc, price asc)表示先 “inStock” 降序, 再 “price” 升序,默認是相關性降序。
wt – (writer type)指定輸出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我們,因為默認沒有打開。
fq – (filter query)過慮查詢,作用:在q查詢符合結果中同時是fq查詢符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找關鍵字mm,并且date_time是20081001到20091031之間的。
q.op – 覆蓋schema.xml的defaultOperator(有空格時用”AND”還是用”OR”操作邏輯),一般默認指定
df – 默認的查詢字段,一般默認指定
qt – (query type)指定那個類型來處理查詢請求,一般不用指定,默認是standard。
- 排除在要排除的詞前加上 “-” (不包含”號) 號
其它
indent – 返回的結果是否縮進,默認關閉,用 indent=true|on 開啟,一般調試json,php,phps,ruby輸出才有必要用這個參數。
version – 查詢語法的版本,建議不使用它,由服務器指定默認值。
[Solr的檢索運算符]
“:” 指定字段查指定值,如返回所有值*:*2
“?”2表示單個任意字符的通配
“*” 表示多個任意字符的通配(不能在檢索的項開始使用*或者?符號)2
“~”2表示模糊檢索,如檢索拼寫類似于”roam”的項這樣寫:roam~將找到形如foam和roams的單詞;roam~0.8,檢索返回相似度在0.8以上的記錄。
2鄰近檢索,如檢索相隔10個單詞的”apache”和”jakarta”,”jakarta apache”~10
“^”2控制相關度檢索,如檢索jakarta apache,同時希望去讓”jakarta”的相關度更加好,那么在其后加上”^”符號和增量值,即jakarta^4 apache
布爾操作符AND、||2
布爾操作符OR、2&&
布爾操作符NOT、!、-2(排除操作符不能單獨與項使用構成查詢)
“+” 存在操作符,要求符號”+”后的項必須在文檔相應的域中存在2
( ) 用于構成子查詢2
2 [] 包含范圍檢索,如檢索某時間段記錄,包含頭尾,date:[200707 TO 200710]
{}2不包含范圍檢索,如檢索某時間段記錄,不包含頭尾
date:{200707 TO 200710}
” 轉義操作符,特殊字符包括+ – & | ! ( ) { } [ ] ^ ” ~ * ? : “
二.高亮
hl-highlight,h1=true,表示采用高亮。可以用h1.fl=field1,field2 來設定高亮顯示的字段。
-
hl.fl: 用空格或逗號隔開的字段列表。要啟用某個字段的highlight功能,就得保證該字段在schema中是stored。如果該參數未被給出,那么就會高 亮默認字段 standard handler會用df參數,dismax字段用qf參數。你可以使用星號去方便的高亮所有字段。如果你使用了通配符,那么要考慮啟用 hl.requiredFieldMatch選項。
-
hl.requireFieldMatch:
如果置為true,除非該字段的查詢結果不為空才會被高亮。它的默認值是false,意味 著它可能匹配某個字段卻高亮一個不同的字段。如果hl.fl使用了通配符,那么就要啟用該參數。盡管如此,如果你的查詢是all字段(可能是使用 copy-field 指令),那么還是把它設為false,這樣搜索結果能表明哪個字段的查詢文本未被找到 -
hl.usePhraseHighlighter:
如果一個查詢中含有短語(引號框起來的)那么會保證一定要完全匹配短語的才會被高亮。 -
hl.highlightMultiTerm
如果使用通配符和模糊搜索,那么會確保與通配符匹配的term會高亮。默認為false,同時hl.usePhraseHighlighter要為true。 -
hl.snippets:
這是highlighted片段的最大數。默認值為1,也幾乎不會修改。如果某個特定的字段的該值被置為0(如f.allText.hl.snippets=0),這就表明該字段被禁用高亮了。你可能在hl.fl=*時會這么用。 -
hl.fragsize:
每個snippet返回的最大字符數。默認是100.如果為0,那么該字段不會被fragmented且整個字段的值會被返回。大字段時不會這么做。 -
hl.mergeContiguous:
如果被置為true,當snippet重疊時會merge起來。 -
hl.maxAnalyzedChars:
會搜索高亮的最大字符,默認值為51200,如果你想禁用,設為-1 -
hl.alternateField:
如果沒有生成snippet(沒有terms 匹配),那么使用另一個字段值作為返回。 -
hl.maxAlternateFieldLength:
如果hl.alternateField啟用,則有時需要制定alternateField的最大字符長度,默認0是即沒有限制。所以合理的值是應該為 -
hl.snippets * hl.fragsize這樣返回結果的大小就能保持一致。
-
hl.formatter:一個提供可替換的formatting算法的擴展點。默認值是simple,這是目前僅有的選項。
-
顯然這不夠用,你可以看看org.apache.solr.highlight.HtmlFormatter.java 和 solrconfig.xml中highlighting元素是如何配置的。
注意在不論原文中被高亮了什么值的情況下,如預先已存在的em tags,也不會被轉義,所以在有時會導致假的高亮。 -
hl.fragmenter:
這個是solr制 定fragment算法的擴展點。gap是默認值。regex是另一種選項,這種選項指明highlight的邊界由一個正則表達式確定。這是一種非典型 的高級選項。為了知道默認設置和fragmenters (and formatters)是如何配置的,可以看看solrconfig.xml中的highlight段。
regex 的fragmenter有如下選項: -
hl.regex.pattern:正則表達式的pattern
-
hl.regex.slop:這是hl.fragsize能變化以適應正則表達式的因子。默認值是0.6,意思是如果hl.fragsize=100那么fragment的大小會從40-160.
三.分組查詢:
1. Field Facet
Facet 字段通過在請求中加入 ”facet.field” 參數加以聲明 , 如果需要對多個字段進行 Facet查詢 , 那么將該參數聲明多次 . 比如
/select?q=聯想 &facet=on &facet.field=cpu &facet.field=videoCard |
各個 Facet 字段互不影響 , 且可以針對每個 Facet 字段設置查詢參數 . 以下介紹的參數既可以應用于所有的 Facet 字段 , 也可以應用于每個單獨的 Facet 字段 . 應用于單獨的字段時通過
f.字段名.參數名=參數值 |
這種方式調用 . 比如 facet.prefix 參數應用于 cpu 字段 , 可以采用如下形式
f.cpu.facet.prefix=Intel |
1.1 facet.prefix
表示 Facet 字段值的前綴 . 比如 ”facet.field=cpu&facet.prefix=Intel”, 那么對 cpu字段進行 Facet 查詢 , 返回的 cpu 都是以 ”Intel” 開頭的 ,”AMD” 開頭的 cpu 型號將不會被統計在內 .
1.2 facet.sort
表示 Facet 字段值以哪種順序返回 . 可接受的值為 true(count)|false(index,lex). true(count) 表示按照 count 值從大到小排列 . false(index,lex) 表示按照字段值的自然順序 (字母 , 數字的順序 ) 排列 . 默認情況下為 true(count). 當 facet.limit 值為負數時 ,默認 facet.sort= false(index,lex).
1.3 facet.limit
限制 Facet 字段返回的結果條數 . 默認值為 100. 如果此值為負數 , 表示不限制 .
1.4 facet.offset
返回結果集的偏移量 , 默認為 0. 它與 facet.limit 配合使用可以達到分頁的效果 .
1.5 facet.mincount
限制了 Facet 字段值的最小 count, 默認為 0. 合理設置該參數可以將用戶的關注點集中在少數比較熱門的領域 .
1.6 facet.missing
默認為 ””, 如果設置為 true 或者 on, 那么將統計那些該 Facet 字段值為 null 的記錄.
1.7 facet.method
取值為 enum 或 fc, 默認為 fc. 該字段表示了兩種 Facet 的算法 , 與執行效率相關 .
enum 適用于字段值比較少的情況 , 比如字段類型為布爾型 , 或者字段表示中國的所有省份.Solr 會遍歷該字段的所有取值 , 并從 filterCache 里為每個值分配一個 filter( 這里要求 solrconfig.xml 里對 filterCache 的設置足夠大 ). 然后計算每個 filter 與主查詢的交集 .
fc( 表示 Field Cache) 適用于字段取值比較多 , 但在每個文檔里出現次數比較少的情況 .Solr 會遍歷所有的文檔 , 在每個文檔內搜索 Cache 內的值 , 如果找到就將 Cache 內該值的count 加 1.
1.8 facet.enum.cache.minDf
當 facet.method=enum 時 , 此參數其作用 ,minDf 表示 minimum document frequency. 也就是文檔內出現某個關鍵字的最少次數 . 該參數默認值為 0. 設置該參數可以減少 filterCache 的內存消耗 , 但會增加總的查詢時間 ( 計算交集的時間增加了 ). 如果設置該值的話 ,官方文檔建議優先嘗試 25-50 內的值 .
2. Date Facet
日期類型的字段在文檔中很常見 , 如商品上市時間 , 貨物出倉時間 , 書籍上架時間等等 . 某些情況下需要針對這些字段進行 Facet. 不過時間字段的取值有無限性 , 用戶往往關心的不是某個時間點而是某個時間段內的查詢統計結果 . Solr 為日期字段提供了更為方便的查詢統計方式 .當然 , 字段的類型必須是 DateField( 或其子類型 ).
需要注意的是 , 使用 Date Facet 時 , 字段名 , 起始時間 , 結束時間 , 時間間隔這 4 個參數都必須提供 .
與 Field Facet 類似 ,Date Facet 也可以對多個字段進行 Facet. 并且針對每個字段都可以單獨設置參數 .
2.1 facet.date
該參數表示需要進行 Date Facet 的字段名 , 與 facet.field 一樣 , 該參數可以被設置多次 , 表示對多個字段進行 Date Facet.
2.2 facet.date.start
起始時間 , 時間的一般格式為 ” 1995-12-31T23:59:59Z”, 另外可以使用 ”NOW”,”YEAR”,”MONTH” 等等 , 具體格式可以參考 org.apache.solr.schema. DateField 的 java doc.
2.3 facet.date.end
結束時間 .
2.4 facet.date.gap
時間間隔 . 如果 start 為 2009-1-1,end 為 2010-1-1.gap 設置為 ”+1MONTH” 表示間隔1 個月 , 那么將會把這段時間劃分為 12 個間隔段 . 注意 ”+” 因為是特殊字符所以應該用 ”%2B” 代替 .
2.5 facet.date.hardend
取值可以為 true|false, 默認為 false. 它表示 gap 迭代到 end 處采用何種處理 . 舉例說明 start 為 2009-1-1,end 為 2009-12-25,gap 為 ”+1MONTH”,hardend 為 false 的話最后一個時間段為 2009-12-1 至 2010-1-1;hardend 為 true 的話最后一個時間段為 2009-12-1 至 2009-12-25.
2.6 facet.date.other
取值范圍為 before|after|between|none|all, 默認為 none.
before 會對 start 之前的值做統計 .
after 會對 end 之后的值做統計 .
between 會對 start 至 end 之間所有值做統計 . 如果 hardend 為 true 的話 , 那么該值就是各個時間段統計值的和 .
none 表示該項禁用 .
all 表示 before,after,all 都會統計 .
舉例 :
&facet=on &facet.date=date &facet.date.start=2009-1-1T0:0:0Z &facet.date.end=2010-1-1T0:0:0Z &facet.date.gap=%2B1MONTH &facet.date.other=all |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"/> <lst name="facet_dates"> <int name="2009-01-01T00:00:00Z">5</int> <int name="2009-11-01T00:00:00Z">1</int> <int name="2009-12-01T00:00:00Z">5</int> <str name="gap">+1MONTH</str> <date name="end">2010-01-01T00:00:00Z</date> <int name="before">180</int> <int name="after">5</int> <int name="between">54</int> </lst> </lst> |
3. Facet Query
Facet Query 利用類似于 filter query 的語法提供了更為靈活的 Facet. 通過 facet.query 參數 , 可以對任意字段進行篩選 .
例 1:
&facet=on &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z] &facet.query=date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z] |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"> <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int> <int name="date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]">3</int> </lst> <lst name="facet_fields"/> <lst name="facet_dates"/> </lst> |
例 2:
&facet=on &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z] &facet.query=price:[* TO 5000] |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"> <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int> <int name="price:[* TO 5000]">116</int> </lst> <lst name="facet_fields"/> <lst name="facet_dates"/> </lst> |
例 3:
&facet=on &facet.query=cpu:[A TO G] |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"> <int name="cpu:[A TO G]">11</int> </lst> <lst name="facet_fields"/> <lst name="facet_dates"/> </lst> |
4. key 操作符
可以用 key 操作符為 Facet 字段取一個別名 .
例 :
&facet=on &facet.field={!key=中央處理器}cpu &facet.field={!key=顯卡}videoCard |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"> <lst name="中央處理器"> <int name="Intel 酷睿2雙核 T6600">48</int> <int name="Intel 奔騰雙核 T4300">28</int>
</lst> <lst name="顯卡"> <int name="ATI Mobility Radeon HD 4">63</int> <int name="NVIDIA GeForce G 105M">24</int> <int name="NVIDIA GeForce GT 240M">21</int> <int name="NVIDIA GeForce G 103M">8</int> <int name="NVIDIA GeForce GT 220M">8</int> <int name="NVIDIA GeForce 9400M G">7</int> <int name="NVIDIA GeForce G 210M">6</int> </lst> </lst> <lst name="facet_dates"/> </lst> |
5. tag 操作符和 ex 操作符
當查詢使用 filter query 的時候 , 如果 filter query 的字段正好是 Facet 字段 , 那么查詢結果往往被限制在某一個值內 .
例 :
&fq=screenSize:14 &facet=on &facet.field=screenSize |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"> <lst name=" screenSize"> <int name="14.0">107</int> <int name="10.2">0</int> <int name="11.1">0</int> </lst> </lst> <lst name="facet_dates"/> </lst> |
可以看到 , 屏幕尺寸 (screenSize) 為 14 寸的產品共有 107 件 , 其它尺寸的產品的數目都是0, 這是因為在 filter 里已經限制了 screenSize:14. 這樣 , 查詢結果中 , 除了 screenSize=14 的這一項之外 , 其它項目沒有實際的意義 .
有些時候 , 用戶希望把結果限制在某一范圍內 , 又希望查看該范圍外的概況 . 比如上述情況 ,既要把查詢結果限制在 14 寸屏的筆記本 , 又想查看一下其它屏幕尺寸的筆記本有多少產品 . 這個時候需要用到 tag 和 ex 操作符 .
tag 就是把一個 filter 標記起來 ,ex(exclude) 是在 Facet 的時候把標記過的 filter 排除在外 .
例 :
&fq={!tag=aa}screenSize:14 &facet=on &facet.field={!ex=aa}screenSize |
返回結果 :
<lst name="facet_counts"> <lst name="facet_queries"/> <lst name="facet_fields"> <lst name=" screenSize"> <int name="14.0">107</int> <int name="14.1">40</int> <int name="13.3">34</int> </lst> </lst> <lst name="facet_dates"/> </lst> |