一旦用戶需要某種信息,就可以立即搜索到這些信息,這種要求再也不是可有可無的了。隨着 Google 和類似的複雜搜索引擎的出現,用戶希望得到高質量的搜索結果,幫助他們快速、輕易地找到所需的信息。經理對您的在線購物站點同樣抱有很高的期望,要求它能 夠提供一個可伸縮、高度可用且易於維護的搜索解決方案,並且安裝這個解決方案不應太昂貴。對於您而言,只是希望事業進步,讓老闆和客戶滿意,以及保持頭腦 清醒。
使用 Apache Solr 可以滿足所有的這些要求,它是一種開放源碼的、基於 Lucene Java 的搜索服務器,易於加入到 Web 應用程序中。Solr 提供了層面搜索、命中醒目顯示並且支持多種輸出格式(包括 XML/XSLT 和 JSON 格式)。它易於安裝和配置,而且附帶了一個基於 HTTP 的管理界面。您可以堅持使用 Solr 的表現優異的基本搜索功能,也可以對它進行擴展從而滿足企業的需要。Solr 還擁有一個活躍的開發者羣體,如有需要,您可以隨時向他們尋求幫助。
這 篇分爲兩部分的文章將介紹 Solr,展示其特性並舉例說明如何將其完全加入到 Web 應用程序中。 我們將首先提供一些 Solr 的基本介紹,包括安裝和配置的說明。然後引入一個示例應用程序(博客界面),您可以通過該程序讓自己熟悉一下 Solr 的各種特性。您將學習如何使用 Solr 來索引和搜索內容並探索 Solr 對層面瀏覽的支持。第 1 部分的最後將簡要介紹一下 Solr 的模式並解釋如何針對示例應用程序的索引結構配置模式。
|
要開始使用 Solr,需安裝以下軟件:
-
Java 1.5
或更高版本。
-
Ant 1.6.x
或更高版本。
- Web 瀏覽器,用來查看管理頁面。建議使用 Firefox
;相比之下使用 Internet Explorer 可能要複雜些。
- servlet 容器,如 Tomcat 5.5 。 本文中的示例假定您的 Tomcat 在 8080 端口上運行,這是 Tomcat 的默認設置。如果運行的是其他 servlet 容器或在其他的端口上運行,則可能要修改給出的 URL 才能訪問示例應用程序和 Solr。我已經假定示例應用程序的各個部分都運行在 Tomcat 的本地主機上。另外還要注意 Solr 以打包的方式與 Jetty 一起提供。
要下載和安裝所有這些應用程序,請參閱 參考資料 。
一旦搭建好運行環境,就可以從 Apache Mirrors Web 站點 下載 Solr 1.1 版。接下來,執行以下操作:
- 停止 servlet 容器。
- 在命令行選擇希望在其中執行操作的目錄,從中輸入
mkdir dw-solr
。 - 輸入
cd dw-solr
。 - 將 Solr 下載版本複製到當前目錄中並解壓縮。
即可得到
apache-solr-1.1.0-incubating
目錄。不用注意 incubating 標記;Solr 早已孵化成熟。 - 將 Solr WAR 文件複製到 servlet 容器的 webapps
目錄中。
-
下載示例應用程序
,將其複製到當前目錄,然後解壓縮,即可在當前工作目錄中得到一個 solr 目錄。本文將一直把它用作 Solr 的主目錄。
- 可以通過以下三種方式之一設置 Solr 的主位置:
- 設置 java 系統屬性
solr.solr.home
(沒錯,就是solr.solr.home
)。 - 配置
java:comp/env/solr/home
的一個 JNDI 查找指向solr
目錄。 - 在包含 solr 目錄的目錄中啓動 servlet 容器。(默認的 Solr 主目錄是當前工作目錄下的 solr 。)
- 設置 java 系統屬性
- 將示例 WAR 文件(位於 dw-solr/solr/dist/dw.war 中)複製到 servlet 容器的 webapps 目錄中,方法與複製 Solr WAR
文件相同。WAR 文件的 Java 的代碼位於 dw-solr/solr/src/java 中,而 JSP 和其他 Web 文件位於
dw-solr/solr/src/webapp 中。
- 要 驗證所有程序都正常運行,請啓動 servlet 容器並將瀏覽器指向 http://localhost:8080/solr/admin/。如果一切順利,您應該看到類似圖 1 所示的頁面。如果沒有出現管理頁面,查看容器日誌中的錯誤消息。另外,確保從 dw-solr 目錄啓動 servlet 容器,以便可以正確地設置 Solr 的主位置。
|
因 爲 Solr 包裝並擴展了 Lucene,所以它們使用很多相同的術語。更重要的是,Solr 創建的索引與 Lucene 搜索引擎庫完全兼容。通過對 Solr 進行適當的配置,某些情況下可能需要進行編碼,Solr 可以閱讀和使用構建到其他 Lucene 應用程序中的索引。此外,很多 Lucene 工具(如 Luke )也可以使用 Solr 創建的索引。
在 Solr 和 Lucene 中,使用一個或多個 Document
來構建索引。Document
包括一個或多個 Field
。Field
包括名稱、內容以及告訴 Solr 如何處理內容的元數據。例如,Field
可以包含字符串、數字、布爾值或者日期,也可以包含您想添加的任何類型。Field
可以使用大量的選項來描述,這些選項告訴 Solr 在索引和搜索期間如何處理內容。我將在本文中稍後詳細討論這些選項。現在,查看一下表 1 中列出的重要屬性的子集:
屬性名稱 | 說明 |
---|---|
indexed | Indexed Field
可以進行搜索和排序。您還可以在 indexed Field
上運行 Solr 分析過程,此過程可修改內容以改進或更改結果。下一節提供了關於 Solr 的分析過程的更多信息。 |
stored | stored Field
內容保存在索引中。這對於檢索和醒目顯示內容很有用,但對於實際搜索則不是必需的。例如,很多應用程序存儲指向內容位置的指針而不是存儲實際的文件內容。 |
您可以在對應用程序內容索引之前運行 Solr 的分析過程來修改這些內容。在 Solr 和 Lucene 中,Analyzer
包括一個 Tokenizer
和一個或多個 TokenFilter
。Tokenizer
負責
生成 Token
,後者在多數情況下對應要索引的詞。TokenFilter
從 Tokenizer
接受 Token
並且可以在索引之前修改或刪除
Token
。
例如,Solr 的 WhitespaceTokenizer
根據空白斷詞,而它的 StopFilter
從搜索結果中刪除公共詞。其他類型的分析包括詞幹提取、同義詞擴展和大小寫摺疊。如果應用程序要求以某種特殊方式進行分析,則 Solr 所擁有的一個或多個斷詞工具和篩選器可以滿足您的要求。
您
還可以在搜索操作期間對查詢應用分析。一個總體規則是:應該對查詢和要索引的文檔運行相同的分析。不熟悉這些概念的用戶常犯的一個錯誤就是:對文檔標記進
行詞幹提取,但不對查詢標記進行詞幹提取,通常導致零搜索匹配。Solr 的 XML 配置使它可以輕易地使用簡單聲明創建 Analyzer
,本文稍後會對此作出展示。
有關 Solr 和 Lucene 的分析工具,以及索引結構和其他功能的更多信息,請參閱 參考資料 。
以下各節將使用實際的示例應用程序向您介紹 Solr 的功能。該示例應用程序是一個基於 Web 的博客界面,您可以使用它來記錄條目、給條目指派元數據,然後索引和搜索條目。在索引和搜索過程的每一步,您都可以選擇顯示發送到 Solr 的命令。
要查看示例應用程序,請將瀏覽器指向 http://localhost:8080/dw/index.jsp。如果一切設置正確(如 “設置 Solr ” 描述的那樣),則您可以看到一個題爲 “Sample Solr Blog Search” 的簡單用戶界面,在標題的正下方有一些菜單項。當您瀏覽本文的兩個部分時,將會瞭解到菜單中的所有主題。
|
在 Solr 中,通過向部署在 servlet 容器中的 Solr Web 應用程序發送 HTTP 請求來啓動索引和搜索。Solr 接受請求,確定要使用的適當 SolrRequestHandler
,然後處理請求。通過 HTTP 以同樣的方式返回響應。默認配置返回 Solr 的標準 XML 響應。您也可以配置 Solr 的備用響應格式。我將在本文的第 2 部分向您展示如何定製請求和響應處理。
索引就是接受輸入(本例中是博客條目、關鍵字和其他元數據)並將它們傳遞給 Solr,從而在 HTTP Post
XML 消息中進行索引的過程。您可以向 Solr 索引 servlet 傳遞四個不同的索引請求:
-
add/update
允許您向 Solr 添加文檔或更新文檔。直到提交後才能搜索到這些添加和更新。
-
commit
告訴 Solr,應該使上次提交以來所做的所有更改都可以搜索到。
-
optimize
重構 Lucene 的文件以改進搜索性能。索引完成後執行一下優化通常比較好。如果更新比較頻繁,則應該在使用率較低的時候安排優化。一個索引無需優化也可以正常地運行。優化是一個耗時較多的過程。
- delete 可以通過 id 或查詢來指定。按 id 刪除將刪除具有指定 id 的文檔;按查詢刪除將刪除查詢返回的所有文檔。
瀏覽到 http://localhost:8080/dw/index.jsp 可以查看索引過程的更多細節。首先爲表單中的每個字段填入適當的條目並按 Submit
按鈕。示例應用程序接受條目、創建 Solr 請求並顯示請求以便在下一個屏幕上查看。清單 1 包含了一個 add
命令的例子,當您按下 Submit
按鈕時向 Solr 發送這個命令。
|
清單 1 的 <doc>
中的每個 field 條目告訴 Solr 應該將哪些 Field
添加到所創建文檔的 Lucene 索引中。可以向 add
命令添加多個 <doc>
。稍後我將解釋 Solr 如何處理這些 field。現在,知道包含清單 1 中指定的七個 field 的文檔將會被索引就足夠了。
當您在 “Solr XML Command” 頁面提交命令時,結果將發往 Solr 進行處理。HTTP
POST
將命令發往在 http://localhost:8080/solr/update 運行的 Solr Update Servlet。如果一切進展順利,則會隨 <result status="0"/>
返回一個 XML 文檔。Solr 使用相同的 URL 自動更新文檔(示例應用程序中的 URL 是 Solr 識別文檔以前是否被添加過所使用的惟一 id)。
現在再添加幾個文檔並提交這些文檔,以便在下一節中有文檔可供搜索。一旦您熟悉 add
命令的語法後,就可以取消選擇 Index
按鈕旁邊的 “Display XML...” 複選框,跳過 “Solr XML
Command” 頁面。本文附帶的 樣例文件
包含了一個很多這些示例中使用的索引版本。
您可以通過在 http://localhost:8080/dw/delete.jsp 頁面輸入文檔的 URL、提交併查看命令,然後將命令提交到 Solr 來刪除文檔。有關索引和刪除命令的更多信息,請參閱 參考資料 中的 “Solr Wiki” 參考。
|
添加文檔後,就可以搜索這些文檔了。Solr 接受 HTTP GET
和 HTTP
POST
查詢消息。收到的查詢由相應的 SolrRequestHandler
進行處理。出於本文的討論目的,我們將使用默認的 StandardRequestHandler
。在本文的第 2 部分,我將向您展示如何爲其他的 SolrRequestHandler
配置 Solr。
要 查看搜索運行,返回到示例應用程序並瀏覽到 http://localhost:8080/dw/searching.jsp。此屏幕應該與索引屏幕非常類似,只是增加了幾個搜索相關的選項。與索引 類似,可以向各種輸入字段中輸入值,選擇搜索參數並將查詢提交給示例應用程序。示例應用程序醒目顯示了一些 Solr 中更常見的查詢參數。這些參數如下所示:
|
-
布爾運算符
:默認情況下,用於合併搜索條目的布爾運算符是
OR
。將它設爲AND
要求匹配的文檔中出現所有的條目。 -
結果數目
:指定返回的最大結果數目。
-
開始
:結果集中開始的偏移量。此參數可用於分頁。
-
醒目顯示
:醒目顯示匹配文檔字段的條目。參考 清單 2
底部的
<lst>
節點。醒目顯示的條目標記爲<em>
。
一旦輸入和提交值後,博客應用程序就返回一個可以立即提交給 Solr 的查詢字符串。提交字符串後,如果一切正常並且存在匹配文檔,則 Solr 返回一個 XML 響應,其中包含了結果、醒目顯示的信息和一些有關查詢的元數據。清單 2 給出了一個示例搜索結果:
|
一條查詢消息可以包含大量的參數,表 2 中對醒目顯示的那些參數進行了描述。參閱 參考資料 中的 “Solr Wiki” 參考可以查看參數的完整清單。
參數 | 描述 | 示例 |
---|---|---|
q | Solr 中用來搜索的查詢。有關該語法的完整描述,請參閱
參考資料
中的 “Lucene QueryParser Syntax”。可以通過追加一個分號和已索引且未進行斷詞的字段(下面會進行解釋)的名稱來包含排序信息。默認的排序是 score desc
,指按記分降序排序。 |
q=myField:Java AND otherField:developerWorks; date
asc
此查詢搜索指定的兩個字段並根據一個日期字段對結果進行排序。 |
start | 將初始偏移量指定到結果集中。可用於對結果進行分頁。默認值爲 0。 |
start=15
返回從第 15 個結果開始的結果。 |
rows | 返回文檔的最大數目。默認值爲 10。 |
rows=25
|
fq | 提供一個可選的篩選器查詢。查詢結果被限制爲僅搜索篩選器查詢返回的結果。篩選過的查詢由 Solr 進行緩存。它們對提高複雜查詢的速度非常有用。 | 任何可以用 q 參數傳遞的有效查詢,排序信息除外。 |
hl | 當 hl=true
時,在查詢響應中醒目顯示片段。默認爲 false。參看醒目顯示參數上的 Solr Wiki 部分可以查看更多選項(見 參考資料
)。 |
hl=true
|
fl | 作爲逗號分隔的列表指定文檔結果中應返回的 Field
集。默認爲 “*
”,指所有的字段。“score”
指還應返回記分。 |
*,score
|
|
最近,似乎所有流行的購物站點都添加了便利的條件列表,幫助用戶根據製造商、價格和作者縮小搜索結果的範圍。這些列表是層面瀏覽的結果,層面瀏覽是一種分類方式,用於對已經返回到有意義的、已證實存在的種類的結果進行分類。層面用於幫助用戶縮小搜索結果的範圍。
通過瀏覽到 http://localhost:8080/dw/facets.jsp 可以查看層面的運行。在這個頁面上,您需要關注兩種輸入形式:
- 一個文本區域,您可以在其中輸入查詢,根據索引中的
all
字段發佈此查詢。將all
字段看作一連串已索引的所有其他字段。(稍後將對此作詳細介紹。) - 一個可以用於分層面的字段下拉列表。此處並未列出所有的已索引字段,其原因馬上就會得到解釋。
輸入一個查詢並從下拉列表中選擇一個層面字段,然後單擊 Submit 與生成的查詢一起傳遞給 Solr。博客應用程序解析結果並返回類似圖 2 中的結果:
在圖 2 中,您可以在頂部看見所有非零值的層面計數,底部則是匹配所提交查詢的兩個搜索結果。單擊示例中的層面鏈接提交原始查詢,另外將
Facet
關鍵字作爲一個新關鍵字。如果原始查詢是 q=Solr
而層面字段是 keywords
,並且單擊圖 2 中的 replication
鏈接,則新查詢將會是
q=Solr AND keywords:replication
。
運行層面不需要打開它或在 Solr 中進行配置,但是可能需要按照新的方式對應用程序內容進行索引。在已索引的字段中完成分層,層面對未進行斷詞的非小寫詞最爲有效。(因此我並未包含 content
字段或 Facet Field 下拉列表中添加到文檔的其他字段。)Facet 字段通常不需要存儲,因爲分層面的總體思想就是顯示人類可讀的值。
另外還要注意 Solr 沒有在層面中創建類別;必須由應用程序自身在索引期間進行添加,正如在索引應用程序時給文檔指派關鍵字一樣。如果存在層面字段,Solr 就提供了查明這些層面及其計數的邏輯。
|
迄今爲止,我已向您介紹了 Solr 的特性,但沒有實際解釋如何配置這些特性。本文的剩餘部分主要介紹配置,首先介紹 Solr 模式(schema.xml)然後向您展示它如何與 Solr 的特性相關聯。
在
編輯器中,最好是支持 XML 標記醒目顯示的編輯器,打開位於 <INSTALL_DIR>/dw-solr/solr/conf 中的
schema.xml 文件。首先要注意的是大量的註釋。如果您以前使用過開放源碼的軟件,您將會爲模式文件中的文檔及整個 Solr
中的文檔欣喜不已。因爲 schema.xml 的註釋非常全面,所以我主要介紹文件的一些關鍵屬性,具體細節可查閱文檔。首先,注意 <schema>
標記中模式(dw-solr)的名稱。Solr
爲每個部署支持一個模式。將來它可能支持多個模式,但是目前只允許使用一個模式。(參閱 參考資料
中的 “Solr Wiki” 參考,瞭解如何簡單地配置 Tomcat 和其他容器,以便爲每個容器使用多個部署。)
模式可以組織爲三部分:
- 類型
- 字段
- 其他聲明
<types>
部分是一些常見的可重用定義,定義了 Solr(和 Lucene)如何處理 Field
。在示例模式中,有 13 個字段類型,按名稱從 string
到 text
。<types>
部分頂部聲明的字段類型(如 sint
和 boolean
)用於存儲 Solr 中的原始類型。在很大程度上,Lucene 只處理字符串,因此需要對整型、浮點型、日期型和雙精度型進行特殊處理才能用於搜索。使用這些字段類型會警告 Solr 使用適當的特殊處理索引內容,不需要人爲干涉。
本文前面的內容中
,我簡要介紹了
Solr 的分析過程的基礎。仔細觀察一下 text
字段類型聲明,您可以看見 Solr 管理分析的細節。清單 3 給出了 text
字段類型聲明:
|
|
首先,注意我在清單 3 中聲明瞭兩個不同的 Analyzer
。雖然 Analyzer
對於索引和搜索並非完全相同,但是它們只是在查詢分析期間的同義詞添加方面有所差別。詞幹提取、停止詞刪除以及相似的操作都被應用於標記,然後才進行索引
和搜索,導致使用相同類型的標記。接下來,注意我首先聲明斷詞工具,然後聲明使用的篩選器。示例應用程序的 Solr 配置按以下步驟進行設置:
- 根據空白進行斷詞,然後刪除所有的公共詞(StopFilterFactory)
- 使用破折號處理特殊的大小寫、大小寫轉換等等。(WordDelimiterFilterFactory);將所有條目處理爲小寫(LowerCaseFilterFactory)
- 使用 Porter Stemming 算法進行詞幹提取 (EnglishPorterFilterFactory)
- 刪除所有的副本(RemoveDuplicatesTokenFilterFactory)
示例分析加入了很多用於改進搜索結果的常見方法,但不應被看作分析文本的惟一方式。每個應用程序都可能有一些自己的分析需求,這個示例或者甚至是 Solr 或 Lucene 中的任何現有 Analyzer
都可能沒有涉及相應需求。請參閱 參考資料
中的 “More Info On Solr Analysis”,瞭解關於分析的更多選項以及如何使用其他 Analyzer
的信息。
繼續介紹模式的 <fields>
部分,查看 Solr 如何處理索引和搜索期間使用的 8 個(實際上是 7 個,外加一個
all
)字段。清單 4 中重複了這些字段:
|
理解字段類型後,您可以清晰地看見如何處理每個字段。例如,url
字段是一個經過索引、存儲和未經分析的 string
字段。
同時,使用 清單
3
中聲明的 Analyzer
來分析 text
字段。all
字段如何處理?all
字段是一個 text
字段,如 title
或 content
一樣,但是它包含了連接在一起的幾個字段的內容,便於使用備用搜索機制(記住層面搜索使用的是 all
字段)。
對於字段的屬性,在 表 1
中您已經瞭解了 indexed
和 stored
的意義。multiValued
屬性是一個特殊的例子,指 Document
可以擁有一個相同名稱添加了多次的 Field
。比如在我們的示例中,可以多次添加 keywords
。omitNorms
屬性告訴 Solr(和 Lucene)不要存儲規範。省略規範對於節省不影響記分的 Field
的內存非常有用,比如那些用於計算層面的字段。
在結束 <fields>
部分之前,簡要介紹一下字段聲明下方的 <dynamicField>
聲明。動態字段是一些特殊類型的字段,可以在任何時候將這些字段添加到任何文檔中,由字段聲明定義它們的屬性。動態字段和普通字段之間的關鍵區別在於前者
不需要在 schema.xml 中提前聲明名稱。Solr 將名稱聲明中的 glob-like 模式應用到所有尚未聲明的引入的字段名稱,並根據其
<dynamicField>
聲明定義的語義來處理字段。例如,<dynamicField name="*_i" type="sint"
indexed="true" stored="true"/>
指一個 myRating_i
字段被 Solr 處理爲 sint
,儘管並未將其聲明爲字段。這種處理比較方便,例如,當需要用戶定義待搜索內容的時候。
最後,schema.xml 文件的最後部分包含了字段和查詢相關的各種聲明。最重要的聲明是 <uniqueKey>url</uniqueKey>
。該聲明用於告訴 Solr 先前聲明的 url
字段是用於確定何時添加或更新文檔的惟一標識符。defaultSearchField
是查詢條目沒有前綴任何字段時 Solr 在查詢中使用的 Field
。示例所使用的查詢與 q=title:Solr
類似。如果您輸入 q=Solr
,則應用默認搜索字段。
最終結果與 q=all:Solr
相同,因爲 all
是博客應用程序中的默認搜索字段。
<copyField>
機制讓您能夠創建 all
字段而無需將文檔的所有內容手工添加到單獨的字段。複製字段是以多種方式索引相同內容的簡便方法。例如,如果您希望提供區分大小寫的精確匹配和忽略大小寫的匹配,則可以使用一個複製字段自動分析收到的內容。然後嚴格按照收到的內容進行索引(所有的字母使用小寫)。
|
目前爲止,您已經安裝了 Solr 並學習瞭如何使用它在示例應用程序中索引和搜索文檔。您也瞭解了 Solr 中層面瀏覽如何工作,並學習瞭如何使用 Solr 的 schema.xml 文件聲明索引結構。本文附帶的 示例應用程序 演示了這些功能和介紹瞭如何爲 Solr 格式化命令。
在 文章的第 2 部分,我將會介紹一些特性,它們將 Solr 從一個簡單的搜索界面擴展成一個可供企業使用的搜索解決方案。您將學習 Solr 的管理界面和高級配置選項,以及性能相關的特性(如緩存、複製和日誌記錄)。我還將簡要討論擴展 Solr 以滿足企業需求的一些方法。同時,充分利用示例應用程序,幫助自己熟悉 Solr 的基本功能。
|
描述 | 名字 | 大小 | 下載方法 |
---|---|---|---|
Solr 樣例應用程序 | j-solr1.zip | 500KB | HTTP |
關於下載方法的信息 |
學習
- “用 Lucene 加速 Web 搜索應用程序的開發
”(Deng Peng Zhou,developerWorks,2006 年 8 月):瞭解關於 Lucene 搜索庫的更多信息,該庫用作 Solr 的基礎庫。
- “Parsing, indexing, and searching XML with Digester and Lucene
”(Otis
Gospodneti,developerWorks,2003 年 6 月):Lucene 初探。
-
Solr 主頁
:學習教程、瀏覽 Javadocs 並隨時關注 Solr 社區。
-
Solr Wiki
:查看 Wiki 獲取關於 Solr 運作的衆多文檔。
-
Solr 分析
:瞭解關於 Solr 的分析器、斷詞工具和標記篩選器工作原理的更多信息。
-
Lucene
QueryParser Syntax
:瞭解關於 Solr 和 Lucene 的查詢解析器語法的更多信息。
-
The Porter Stemming Algorithm
:瞭解關於 Solr 使用的詞幹提取算法的更多信息。
-
Public Websites using Solr
:使用 Solr 功能的 Web 站點的清單。
-
Lucene Java 主頁
:探索 Solr 的起源。
-
Lucene In Action
(Otis
Gospodneti and Erik Hatcher;Manning,2004 年):對 Lucene 有興趣的人的必讀之作。
- developerWorks Java 技術專區 :關於 Java 編程各個方面的數百篇文章。