標準查詢解析器

Solr 的預設查詢解析器也稱為「lucene」解析器。

標準查詢解析器的主要優點是它支援強大且相當直覺的語法,讓您能夠建立各種結構化查詢。最大的缺點是它對語法錯誤非常不寬容,相較之下,DisMax 查詢解析器旨在盡可能減少錯誤。

標準查詢解析器參數

除了常用查詢參數分面參數、醒目提示參數和MoreLikeThis 參數之外,標準查詢解析器還支援下表中所述的參數。

q

使用標準查詢語法定義查詢。此參數為必要參數。

q.op

指定查詢運算式的預設運算子。可能的值為「AND」或「OR」。

df

指定預設的可搜尋欄位。

sow

依空白分割。如果設定為 true,則會針對每個以空白分隔的詞彙單獨調用文字分析。預設值為 false;以空白分隔的詞彙序列會一次性提供給文字分析,以啟用對詞彙序列進行操作的分析篩選器的正確功能,例如,多字同義詞和 shingle。

預設參數值在 solrconfig.xml 中指定,或由請求中的查詢時間值覆寫。

標準查詢解析器回應

預設情況下,標準查詢解析器的回應會包含一個未命名的 <result> 區塊。如果使用了 debug 參數,則會額外回傳一個名為 "debug" 的 <lst> 區塊。此區塊會包含有用的除錯資訊,包括原始查詢字串、已解析的查詢字串,以及 <result> 區塊中每個文件的說明資訊。如果同時使用了 explainOther 參數,則會針對符合該查詢的所有文件提供額外的說明資訊。

範例回應

本節提供標準查詢解析器回應的範例。

下方的 URL 會提交一個簡單的查詢,並要求 XML 回應寫入器使用縮排,以使 XML 回應更易於閱讀。

https://127.0.0.1:8983/solr/techproducts/select?q=id:SP2514N&wt=xml

結果

<response>
<responseHeader><status>0</status><QTime>1</QTime></responseHeader>
<result numFound="1" start="0">
 <doc>
  <arr name="cat"><str>electronics</str><str>hard drive</str></arr>
  <arr name="features"><str>7200RPM, 8MB cache, IDE Ultra ATA-133</str>
    <str>NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor</str></arr>
  <str name="id">SP2514N</str>
  <bool name="inStock">true</bool>
  <str name="manu">Samsung Electronics Co. Ltd.</str>
  <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
  <int name="popularity">6</int>
  <float name="price">92.0</float>
  <str name="sku">SP2514N</str>
 </doc>
</result>
</response>

以下是一個使用有限欄位列表的查詢範例。

https://127.0.0.1:8983/solr/techproducts/select?q=id:SP2514N&fl=id+name&wt=xml

結果

<response>
<responseHeader><status>0</status><QTime>2</QTime></responseHeader>
<result numFound="1" start="0">
 <doc>
  <str name="id">SP2514N</str>
  <str name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133</str>
 </doc>
</result>
</response>

為標準查詢解析器指定詞語

對標準查詢解析器的查詢會被分解為詞語和運算子。詞語有兩種型別:單一詞語和詞組。

  • 單一詞語是單一個字,例如 "test" 或 "hello"。

  • 詞組是以雙引號括起來的一組字,例如 "hello dolly"。

多個詞語可以使用布林運算子組合在一起,形成更複雜的查詢(如下所述)。

重要的是,用於查詢的分析器解析詞語和詞組的方式,必須與用於索引的分析器解析詞語和詞組的方式一致;否則,搜尋可能會產生非預期的結果。

詞語修飾符

Solr 支援多種詞語修飾符,可根據需要為搜尋增加彈性或精確度。這些修飾符包括萬用字元、用於使搜尋「模糊」或更廣泛的字元等等。以下章節將詳細說明這些修飾符。

萬用字元搜尋

Solr 的標準查詢解析器支援在單一詞語中使用單一和多個字元的萬用字元搜尋。萬用字元可以應用於單一詞語,但不能應用於搜尋詞組。

萬用字元搜尋類型 特殊字元 範例

單一字元(匹配單一字元)

?

搜尋字串 te?t 會匹配 test 和 text。

多個字元(匹配零個或多個連續字元)

*

萬用字元搜尋: tes* 會匹配 test、testing 和 tester。您也可以在詞語中間使用萬用字元。例如: te*t 會匹配 test 和 text。 *est 會匹配 pest 和 test。

模糊搜尋

Solr 的標準查詢解析器支援基於 Damerau-Levenshtein 距離或編輯距離演算法的模糊搜尋。模糊搜尋會找出與指定詞語相似但不一定完全匹配的詞語。若要執行模糊搜尋,請在單字詞語的結尾使用波浪號 ~ 符號。例如,若要搜尋拼寫與 "roam" 相似的詞語,請使用模糊搜尋

roam~

此搜尋將匹配 roams、foam 和 foams 等詞語。它也會匹配單字 "roam" 本身。

可選的距離參數指定允許的最大編輯次數,介於 0 到 2 之間,預設為 2。例如

roam~1

這會匹配 roams 和 foam 等詞語,但不會匹配 foams,因為它的編輯距離為 "2"。

在許多情況下,詞幹還原(將詞語簡化為共同詞幹)可以產生與模糊搜尋和萬用字元搜尋類似的效果。

鄰近搜尋

鄰近搜尋會尋找彼此之間在特定距離內的詞語。

若要執行鄰近搜尋,請在搜尋詞組的結尾加入波浪號 ~ 和數值。例如,若要在文件中搜尋彼此相隔 10 個單字內的 "apache" 和 "jakarta",請使用搜尋

"jakarta apache"~10

此處指的距離是匹配指定詞組所需的詞語移動次數。在上面的範例中,如果 "apache" 和 "jakarta" 在欄位中相隔 10 個空格,但 "apache" 出現在 "jakarta" 之前,則需要超過 10 次的詞語移動才能將詞語移動到一起,並將 "apache" 放置在 "jakarta" 的右側,中間有一個空格。

存在搜尋

欄位的存在搜尋會匹配該欄位存在值的所有文件。若要查詢欄位是否存在,只需在搜尋中使用萬用字元代替詞語即可。

field:*

如果欄位有任何值,即使是通常被認為「不存在」的值(例如,NaN"" 等),該欄位也會被視為「存在」。

範圍搜尋

範圍搜尋會為欄位指定一個值範圍(具有上限和下限的範圍)。查詢會匹配指定欄位或多個欄位的值落在範圍內的文件。範圍查詢可以包含或排除上限和下限。排序是按字典順序完成的,數字欄位除外。例如,下面的範圍查詢會匹配所有 popularity 欄位的值介於 52 到 10,000(含)之間的文件。

popularity:[52 TO 10000]

範圍查詢不限於日期欄位,甚至不限於數字欄位。您也可以將範圍查詢用於非日期欄位

title:{Aida TO Carmen}

這會尋找標題介於 Aida 和 Carmen 之間,但不包括 Aida 和 Carmen 的所有文件。

查詢周圍的方括號會決定其包含性。

  • 方括號 [ & ] 表示一個包含性的範圍查詢,會匹配包括上限和下限的值。

  • 大括號 { & } 表示一個排除性的範圍查詢,會匹配上限和下限之間的值,但不包括上限和下限本身。

  • 您可以混合使用這些類型,使範圍的一端是包含性的,而另一端是排除性的。以下是一個範例:count:{1 TO 10]

萬用字元 * 也可用於一個或兩個端點,以指定開放式範圍查詢。這是與 Lucene 的傳統查詢解析器的差異

  • field:[* TO 100] 會尋找所有小於或等於 100 的欄位值。

  • field:[100 TO *] 會尋找所有大於或等於 100 的欄位值。

  • field:[* TO *] 會尋找任何具有介於該欄位類型有效值 -Infinity 和 +Infinity 之間的值的文件。

使用萬用字元匹配 NaN

對於大多數欄位,無界限範圍查詢 field:[* TO *] 等同於存在查詢 field: *。但是,對於支援 NaN 值的 float/double 類型,這兩個查詢的執行方式不同。

  • field:* 會匹配所有現有值,包括 NaN

  • field:[* TO *] 會匹配所有實數值,不包括 NaN

使用 "^" 提升詞語

Solr 會根據找到的詞語提供匹配文件的相關性級別。若要提升詞語,請在搜尋詞語的結尾使用插入符號 ^ 和提升因子(數字)。提升因子越高,詞語的相關性就越高。

提升可讓您透過提升詞語來控制文件的相關性。例如,如果您正在搜尋

"jakarta apache",並且您希望 "jakarta" 詞語更具相關性,您可以將 ^ 符號連同提升因子一起直接新增在詞語後面來提升它。例如,您可以輸入

jakarta^4 apache

這會使包含 jakarta 詞語的文件看起來更具相關性。您也可以提升詞組,如以下範例所示

"jakarta apache"^4 "Apache Lucene"

預設情況下,提升因子為 1。雖然提升因子必須為正數,但它可以小於 1(例如,它可以是 0.2)。

使用 "^=" 的常數分數

常數分數查詢是使用 <query_clause>^=<score> 建立的,它會將整個子句設定為指定的分數,用於符合該子句的任何文件。當您只關心特定子句的匹配項,而不希望其他相關性因素(例如詞語頻率(詞語在欄位中出現的次數))或反向文件頻率(整個索引中詞語在欄位中的罕見程度)時,這是理想的選擇。

範例

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

查詢特定欄位

Solr 中編入索引的資料組織在 欄位中,這些欄位在 結構描述中定義。搜尋可以利用欄位來為查詢增加精確度。例如,您可以僅在特定欄位(例如標題欄位)中搜尋詞語。

結構描述會將一個欄位定義為預設欄位。如果您未在查詢中指定欄位,Solr 將僅搜尋預設欄位。或者,您可以在查詢中指定不同的欄位或欄位組合。

若要指定欄位,請輸入欄位名稱,然後輸入冒號 ":",再輸入您要在欄位中搜尋的詞語。

例如,假設索引包含兩個欄位,標題和文字,並且文字是預設欄位。如果您要尋找一個名為「The Right Way」且包含文字「don’t go this way」的文件,您可以在搜尋查詢中包含以下任一詞語

title:"The Right Way" AND text:go

title:"Do it right" AND go

由於文字是預設欄位,因此不需要欄位指示符;因此,上述第二個查詢會省略它。

此欄位僅對其直接前方的詞彙有效,因此查詢 title:Do it right 將只會在 title 欄位中找到 "Do"。它會在預設欄位(在此範例中為 text 欄位)中找到 "it" 和 "right"。

標準查詢剖析器支援的布林運算子

布林運算子允許您將布林邏輯應用於查詢,要求欄位中存在或不存在特定詞彙或條件才能比對文件。下表總結了標準查詢剖析器支援的布林運算子。

布林運算子 替代符號 說明

AND

&&

要求布林運算子兩側的詞彙都存在,才能比對成功。

NOT

!

要求後面的詞彙不存在。

OR

||

要求至少存在其中一個詞彙(或兩個詞彙都存在),才能比對成功。

+

要求後面的詞彙必須存在。

-

禁止後面的詞彙(也就是說,比對不包含該詞彙的欄位或文件)。- 運算子的功能與布林運算子 ! 類似。由於 Google 等熱門搜尋引擎會使用它,因此某些使用者社群可能會更熟悉它。

布林運算子允許透過邏輯運算子組合詞彙。Lucene 支援 AND、「+」、OR、NOT 和「-」作為布林運算子。

使用 AND 或 NOT 等關鍵字指定布林運算子時,關鍵字必須全部以大寫字母顯示。
標準查詢剖析器支援上表中列出的所有布林運算子。DisMax 查詢剖析器僅支援 +-

OR 運算子是預設的連接運算子。這表示,如果兩個詞彙之間沒有布林運算子,則會使用 OR 運算子。OR 運算子會連結兩個詞彙,並且只要文件中存在其中一個詞彙,就會找到符合的文件。這相當於使用集合的聯集。符號 || 可以用來取代文字 OR。

若要搜尋包含「jakarta apache」或僅包含「jakarta」的文件,請使用下列查詢

"jakarta apache" jakarta

"jakarta apache" OR jakarta

布林運算子「+」

+ 符號(也稱為「required」運算子)要求 + 符號之後的詞彙必須存在於至少一個文件中的欄位內,查詢才能傳回比對結果。

例如,若要搜尋必須包含「jakarta」且可能包含或不包含「lucene」的文件,請使用以下查詢

+jakarta lucene

標準查詢剖析器和 DisMax 查詢剖析器都支援此運算子。

布林運算子 AND ("&&")

AND 運算子會比對單一文件的文字中任何位置都存在兩個詞彙的文件。這相當於使用集合的交集。符號 && 可以用來取代文字 AND。

若要搜尋包含「jakarta apache」和「Apache Lucene」的文件,請使用以下任一查詢

"jakarta apache" AND "Apache Lucene"

"jakarta apache" && "Apache Lucene"

布林運算子 NOT ("!")

NOT 運算子會排除包含 NOT 之後詞彙的文件。這相當於使用集合的差集。符號 ! 可以用來取代文字 NOT。

以下查詢會搜尋包含詞組「jakarta apache」但不包含詞組「Apache Lucene」的文件

"jakarta apache" NOT "Apache Lucene"

"jakarta apache" ! "Apache Lucene"

布林運算子「-」

- 符號或「prohibit」運算子會排除包含 - 符號之後詞彙的文件。

例如,若要搜尋包含「jakarta apache」但不包含「Apache Lucene」的文件,請使用以下查詢

"jakarta apache" -"Apache Lucene"

跳脫特殊字元

當這些字元出現在查詢中時,Solr 會將其視為特殊意義

+ - && || ! ( ) { } [ ] ^ " ~ * ? : /

為了讓 Solr 將這些字元解譯為字面值,而不是特殊字元,請在字元前加上反斜線字元 \。例如,若要搜尋 (1+1):2,而不要讓 Solr 將加號和括號解譯為用於制定具有兩個詞彙的子查詢的特殊字元,請跳脫這些字元,方法是在每個字元前加上反斜線

\(1\+1\)\:2

將詞彙分組以形成子查詢

Solr 支援使用括號將子句分組以形成子查詢。如果您想要控制查詢的布林邏輯,這非常有用。

以下查詢會搜尋「jakarta」或「apache」以及「website」

(jakarta OR apache) AND website

這會增加查詢的精確度,要求必須存在詞彙「website」,以及詞彙「jakarta」和「apache」的其中一個。

在欄位中分組子句

若要將兩個或多個布林運算子應用於搜尋中的單一欄位,請將布林子句置於括號內。例如,以下查詢會搜尋包含單字「return」和詞組「pink panther」的 title 欄位

title:(+return +"pink panther")

查詢中的註解

查詢字串支援 C 樣式註解。

範例

"jakarta apache" /* 這是正常查詢字串中間的註解 */ OR jakarta

註解可以巢狀結構。

Lucene 的 Classic Query Parser 與 Solr 的 Standard Query Parser 之間的差異

Solr 的標準查詢剖析器源自 Lucene 的「經典」QueryParser 的變體。它在以下方面有所不同

  • * 可用於任一端點或兩個端點,以指定開放式範圍查詢,或者單獨使用作為存在查詢。

    • field:[* TO 100] 會尋找所有小於或等於 100 的欄位值

    • field:[100 TO *] 會尋找所有大於或等於 100 的欄位值

    • field:[* TO *] 會尋找欄位的值介於 -InfinityInfinity 之間(不包含 NaN)的所有文件。

    • field:* 會尋找欄位存在(也就是說,具有任何值)的所有文件。

  • 允許純粹的負數查詢(所有子句都禁止)(僅作為頂層子句)

    • -inStock:false 會尋找所有 inStock 不是 false 的欄位值

    • -field:* 會尋找欄位沒有值的所有文件。

  • 支援使用 local-params 語法將任何類型的查詢剖析器作為巢狀子句,以嵌入式 Solr 查詢(子查詢)。

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

      陷阱:請小心不要在開頭以 {! 作為查詢的開頭,這會變更整個查詢字串的剖析方式,如果還有其他子句,這可能不是您想要的。因此,如果將上述範例反轉,讓子查詢先出現,則若沒有前導空格,將無法如預期運作。

      也可以使用神奇欄位 _query_ 進行子查詢,並使用神奇欄位 _val_ 進行函式查詢,但由於它不太清楚,因此應視為已淘汰。範例:_val_:"recip(rord(myfield),1,2,3)"

  • 支援特殊的 filter(…​) 語法,表示某些查詢子句應快取在篩選器快取中(作為常數分數布林查詢)。這允許將子查詢快取並重複用於其他查詢。例如,inStock:true 將快取並重複用於以下三個查詢中

    • q=features:songs OR filter(inStock:true)

    • q=+manu:Apple +filter(inStock:true)

    • q=+manu:Apple & fq=inStock:true

      這甚至可以用來快取複雜篩選查詢的個別子句。在以下第一個查詢中,將有 3 個項目新增至篩選器快取(頂層 fq 和兩個 filter(…​) 子句),而在第二個查詢中,將有 2 個快取命中,以及 1 個新的快取插入(針對新的頂層 fq

    • 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」)是常數評分(所有符合的文件都會獲得相同分數)。不會使用評分因子 TF、IDF、索引增強和「coord」。符合的詞彙數目沒有限制(如先前版本的 Lucene 中所示)。

  • 使用 <query_clause>^=<score> 建立常數分數查詢,它會將整個子句設定為任何符合該子句之文件的指定分數

    • q=(description:blue color:blue)^=1.0 title:blue^=5.0

指定日期和時間

針對日期欄位進行查詢時,必須使用適當的日期格式。針對確切日期值的查詢將需要加上引號或跳脫字元,因為 : 是用來表示欄位查詢的剖析器語法

  • 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]