solr的查詢語法

lixiaobu 8年前發布 | 2K 次閱讀 Java 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>

 本文由用戶 lixiaobu 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!