1. 程式人生 > >Solr 的核心就是搜尋

Solr 的核心就是搜尋

Solr 的主要功能就是強大的查詢處理。在本文中,你將會看到 Solr 的查詢處理,這將會幫助你瞭解為什麼說 Solr 是強大的搜尋技術。

在本文中,請注意每個查詢和 Solr 返回的文件之間的連結,以及返回的結果文件中的排序。這將有助於你像搜尋引擎那樣去思考問題,以後我們會逐漸覆蓋核心的搜尋概念。

探索 Solr 的查詢表單

你可能已經使用過 Solr 的查詢表單來執行查詢所有文件的查詢。現在,我們來快速看看這個表單的其它特性,這樣可以讓你對 Solr 支援的查詢型別有個直觀的瞭解。下圖對這個表單的重點部分進行了註釋。請花點時間來逐個瞭解這些註釋:

1

在上圖中,我們編寫了一個查詢,並且如果使用《[Solr] 快速入門》中新增的文件的話,那麼結果中將會返回兩個示例文件。像上圖中的表單那樣填寫,並在你自己的環境中執行一次,看看是否真的返回了兩個示例文件?

所有和 Solr 核心服務的互動過程都是使用 HTTP 請求。當你填寫了查詢表單並點選查詢後,將會發起一個 HTTP GET 請求到 Solr。下圖展示了你在上圖中點選查詢後發起的 HTTP GET 請求,注意,真正的 HTTP GET 請求是沒有換行符的,這裡使用換行符是為了更加清晰地看清楚每個引數:

2

更多的查詢示例?

我們以後會更深入地理解查詢。如果你現在就想看更多的查詢示例,那麼建議你使用瀏覽器開啟  $SOLR_INSTALL/docs/tutorial.html 這個 HTML 文件,你將會看到使用示例文件進行查詢的更多示例。

Solr 的這個查詢表單並不是為終端使用者設計的。Solr 提供了這個查詢表單是為開發人員和管理員提供了一種發起 HTTP 查詢的簡單方式,而不用去手動編寫 HTTP 請求或使用客戶端應用程式。但是,我們必須要很清楚的知道,編寫基於 Solr 的應用程式,你有責任要開發使用者介面(UI)。本文的後面你將會看到,Solr 提供了可定製的查詢 UI,可以幫助你編寫你自己的需要的查詢介面。

當你執行查詢後 Solr 返回了什麼?

我們前面已經看到了傳送到 Solr 的資料是什麼,接下來我們看看從 Solr 返回的結果。Solr 返回的是匹配查詢條件的文件,以及讓你的 Solr 客戶端提供高質量搜尋體驗的附加資訊。操作資料是通過 Solr 客戶端,而 Solr 本身只會返回原始資料和 features,你需要自己為使用者建立高質量的搜尋體驗。

下圖展示了上一節中的例子返回的結果。可以看到,返回的是 XML 格式並且按價格從低到高排序。每個文件都包含了 iPod 關鍵字。結果中沒有分頁,因為一共只有兩條資料。

3

目前為止,我們只看過 XML 格式的返回值,但是 Solr 還支援其它格式,例如 CSV(comma-separated  values), JavaScript  Object  Notation  (JSON), 和滿足流行語言語言規範的格式。例如,Solr 可以返回 Python 標準格式,可以通過 eval 方法將響應安全地轉換為 Python 物件。

檢索排名

Solr 的檢索過程與資料庫檢索和其他 NoSQL 資料庫檢索的組要不同就是檢索排名。Solr 通過檢索的相關度來對文件排序,相關度最高的文件最先列出。

我們使用前面已經新增好索引的例子來看看檢索排名是如何工作的。最開始,輸入 iPod 到 q 文字框,輸入 name,features,score 到 fl 文字域,然後點選執行。那麼將會返回三個文件,並且按照評分降序排列。檢查一下查詢結果,看看是否同意這個簡單查詢的排序。

直觀看來,這樣的排序是在情理之中的,因為關鍵字 iPod 在第一個文件中一共出現了三次,兩次在 name 中,一次在 features 中;而在另外兩個文件中都只出現了一次。score 欄位的數字用於 Lucene 內部進行相關度排序,這個值在不同的查詢之間沒有可比性。每個匹配查詢的文件都會分配一個針對這個查詢的相關性得分,結果按照得分降序排列。

接下來,將查詢關鍵字改為 iPod power,你將會看到返回相同的三個文件,並且順序也和之前是一樣的。這是因為所有三個文件中的 name 或 features 欄位中都包含了查詢的關鍵字。但是我們可以看到前兩個文件的得分非常接近:第二個查詢的得分是 1.521 和 1.398,第一個查詢的得分是 1.333 和 0.770。這也是合理的,因為 power 在第二個文件中出現了兩次,所以用 iPod power 進行查詢的得分應該比通過 iPod 進行查詢的得分要高。

現在,將查詢關鍵字改為 iPod power^2,這將會把 power 關鍵字的權重提升為 2。簡單說來,這意味著進行查詢的時候 power 關鍵字比 iPod 關鍵字重要兩倍,預設的權重是 1。執行查詢後,返回了相同的三個文件,但是它們的順序有所不同。現在,結果中最頂部的文件是 Belkin Mobile Power Cord for iPod w/ Dock,因為在它的 name 和 features 欄位中包含了 power 關鍵字,我們之前說過,在這次查詢中 Solr 會認為 power 關鍵字比 iPod 重要兩倍。

現在,你已經感受過了什麼是搜尋排名。我們接下來看看搜尋處理的其它特性,我們先來看看如何使用分頁和排序。

分頁和排序

我們的樣例中,Solr 只索引了 32 個文件,但是真實的 Solr 專案一般會包含數百萬的文件。你可以想象一下將 Solr 應用到一個電子產品的網上商店,如果使用 iPod 關鍵字進行查詢,可能會匹配到幾千個產品和周邊配件。要確保快速返回結果,特別是在頻寬有限的手持裝置上面,你不可能一次性返回幾千條資料,即便將最相關的資料一次性返回也是不行的。

分頁

解決方案是通過分頁來返回資料,並通過導航來請求更多頁的資料。在 Solr 查詢處理中,分頁是是第一類的概念,在每個查詢中都需要控制每頁的記錄數(rows)和開始位置(start)。如果在請求中沒有設定,那麼 Solr 使用的預設每頁記錄數是 10,但是你可以在發起查詢請求的時候通過 rows 引數進行控制。要請求下一頁的結果,可以通過每頁記錄數來增加 start 引數的值。例如,如果你現在返回了第一頁的結果(start=0),現在你要查詢下一頁,你可以通過每頁記錄數來增加 start 引數的值,例如 start = 10。

要記住很重要的一點是讓每頁記錄數在滿足需求的情況下,儘可能的小,因為底層的 Lucene 所有並沒有為一次返回大量文件做優化。相反,底層的 Lucene 是對查詢過程進行了優化,因此底層的資料結構是設計用於返回最佳匹配和最高評分的文件。一旦搜尋結果確定下來,Solr 需要重新構建每個文件結構,大多數情況下是從磁碟讀取資料。為了效率,它使用了智慧快取,但是相比查詢過程來說,構建查詢結果是一個比較慢的過程,尤其是當每頁記錄數大的時候。因此,為了更高的效率,在 Solr 中要讓每頁記錄數儘可能的小。

排序

就像前文所述,返回結果是按評分來進行降序排列(從高到低)。但是,你也可以請求 Solr 的返回結果按照某個欄位來進行排序。前面已經看過了結果按照價格來升序排列,產品價格最低的排在最前面。

排序和分頁具有很強的相關性,因為排序規則決定了頁面的位置。為了幫助你更好的瞭解排序和分頁,我們考慮一下這個問題,如果只設置了分頁規則而沒有設定排序規則,Solr 是否每次都會返回固定的結果?

表面上看來,這個問題的結果很明顯,因為如果沒有設定排序規則,那麼結果就會按照評分來進行降序排列。但是,如果查詢的結果中有相同的評分呢?例如,如果你查詢 inStock:true,那麼所有匹配的文件都有相同的評分;你可以通過查詢表單來驗證這個結果。

事實證明,儘管評分一致,Solr 也能保持每次返回值的排序是固定的。這是因為 Solr 找到所有匹配的文件然後再應用排序和分頁。Solr 將會保持跟蹤整個文件集的排序和分頁。另外,順便說一下,如果所有文件的評分都一樣,那麼將會返回索引順序,這是基於內部由 Lucene 管理的文件 ID。這個內部的文件 ID 大致等同於文件被索引的順序,但是你不需要依賴這個值來進行排序,因為當你的索引發生變更時這個值有可能改變。