2022-07-07 分類: 網(wǎng)站建設(shè)
使用 Sphinx 索引內(nèi)容、快速查找文本并提供有用的搜索結(jié)果
此文出處:成都網(wǎng)站建設(shè)-----成都創(chuàng)新互聯(lián)(www.rwnh.cn)技術(shù)總監(jiān)博客
雖然 Google 及其系列產(chǎn)品幾乎無所不能,但是 Web 形式的強大搜索引擎并不能很好地適用于每個站點。如果站點內(nèi)容已被高度專注化或已明確分類,那就需要使用 Sphinx 和 PHP 來創(chuàng)建一個優(yōu)化的本地搜索系統(tǒng)。
在 Internet 時代,人們希望信息能夠像快餐一樣被打包起來:能夠快速無障礙使用,并且分為很小的單位(或者是以字節(jié)大小為單位?)。實際上,為了滿足急躁而又渴求信息的用戶的需求,甚至最普通的 Web 站點現(xiàn)在都要求具有快速瀏覽樣式的各種菜單:
RSS 是比薩快遞員,會把新鮮出爐的比薩送上門。 網(wǎng)絡(luò)日志是當(dāng)?shù)氐闹胁宛^,為您獻上喜愛的風(fēng)味菜肴。 論壇是家常便飯(或者可能更恰當(dāng)?shù)卣f,“動物屋” 中搶奪食物的場景)。 而搜索就像在當(dāng)?shù)氐牟蛷d吃自助晚餐一樣:不斷將想吃的食物填滿盤子就行,只要您的食道 —— 還有您的椅子 —— 撐得住。幸運的是,PHP 開發(fā)人員可以找到各種 RSS、blog 和論壇軟件來創(chuàng)建或者改進站點。而且,雖然 Google 和其他搜索站點幾乎無所不能并且執(zhí)行過濾通信,但是搜索引擎并不一定會良好地適應(yīng)各個站點。
例如,如果 Web 站點提供成百上千的全新和翻新的保時捷汽車零件,Google 可能通過諸如 “Carrera parts” 之類的廣義搜索找到您的站點,但是對于更具體的 “used 1991 Porsche 911 Targa headlight bezel” 查詢,它可能不會得到精確結(jié)果。
如果站點內(nèi)容高度專注化,或者訪問者期望搜索功能與現(xiàn)實工作流類似,那么較好在 Web 的全局搜索引擎基礎(chǔ)上增加一個為您的站點量身定做的本地搜索系統(tǒng)(有關(guān)專注化搜索的更多實例,請參閱 “A needle in a billion haystacks”)。
通過本文了解如何向 PHP 站點中添加一個快速、高效、開源和免費的搜索引擎。本文沒有開發(fā)可見的 Web 站點。相反,重點討論交付有效搜索結(jié)果所需的組件:數(shù)據(jù)庫、索引、搜索引擎和 PHP 應(yīng)用程序編程接口 (API)。
訪問優(yōu)秀的 sphinx要為站點提供自定義搜索功能,您必須有數(shù)據(jù)源和搜索該數(shù)據(jù)源的功能。對于 Web 應(yīng)用程序,數(shù)據(jù)源通常是一個關(guān)系數(shù)據(jù)庫,其中內(nèi)置了一些搜索功能(Equality 是一個簡單的搜索運算符,與 SQL 運算符LIKE一樣)。但是,一些搜索可能比數(shù)據(jù)庫可以執(zhí)行的搜索更加具體,或者搜索可能過于復(fù)雜,而導(dǎo)致固有的 SQLJOIN反應(yīng)遲鈍。
許多站點提供特定于某一個行業(yè)、職業(yè)或者娛樂的內(nèi)容,例如醫(yī)藥、法律、音樂和汽車維修。深入研究這些內(nèi)容可能要求使用特殊工具或者培訓(xùn),或者僅需要使用一個索引來生成相關(guān)的實用結(jié)果。
下面是一些需要定制搜索系統(tǒng)的常見搜索場景:
查找 Joe Hockey 所撰寫的關(guān)于斯坦利杯 (Stanley Cup) 的所有文章。 查找 HP LaserJet 3015 All-in-One 打印機的最新驅(qū)動程序。 查找 Dinosaur Jr. 參與大衛(wèi)深夜脫口秀節(jié)目的電視片段。要加速搜索,您可以重新安排表,并由此簡化底層查詢(表和 SQL 查詢優(yōu)化高度依賴于模式和引擎。可通過在線搜索查找有關(guān)數(shù)據(jù)庫性能的各種文章和書籍)。此外,您可以添加一個專門化的搜索引擎。應(yīng)用哪種形式的搜索引擎還依賴于數(shù)據(jù)的形式(和數(shù)量)和預(yù)算。有許多選擇可用:您可以將一個 Google 工具連接到您的網(wǎng)絡(luò)中,購買 Endeca 或其他大型商業(yè)搜索產(chǎn)品,或者嘗試 Lucene。但是在很多情況下,使用商業(yè)產(chǎn)品都有點小題大做,或者浪費運營預(yù)算,并且 Lucene 在 2007 年 7 月編寫時并未提供 PHP API。
作為一個備選方案,考慮一下Sphinx,它是一種開源和免費的搜索引擎,可以非??焖俚厮阉魑谋?。例如,在一個幾乎有 300,000 行及五個索引列(每列包含大約 15 個單詞)的活動數(shù)據(jù)庫中,Sphinx 可以在 1/100 秒內(nèi)得到 “這些單詞中任何一個單詞” 的搜索結(jié)果(在運行 Debian Linux? Sarge 的 2-GHz AMD Opteron 處理器、1 GB RAM 的計算機上)。
Sphinx 提供了大量功能,包括:
它可以為能夠表示為字符串的所有數(shù)據(jù)建立索引。 它可以以各種方式為相同數(shù)據(jù)建立索引。對于多個索引,每個索引都針對特定目的而定制,您可以選擇最適當(dāng)?shù)乃饕齺韮?yōu)化搜索結(jié)果。 它可以把屬性與每條索引數(shù)據(jù)關(guān)聯(lián)起來。然后您可以使用一個或多個屬性來進一步過濾搜索結(jié)果。 它支持詞法,因此搜索單詞 “cats” 還會找到詞根 “cat”。 您可以在許多計算機中分發(fā) Sphinx 索引,從而提供故障恢復(fù)功能。 它可以創(chuàng)建任意長度的單詞前綴索引和可變長度的中綴子字符串的索引。例如,一個零件號可以是 10 個字符寬。前綴索引將匹配位于字符串開頭處的所有可能的子字符串。中綴索引將匹配在字符串內(nèi)任意位置的子字符串。 您可以在 MySQL V5 內(nèi)將其作為存儲引擎運行,降低使用其他守護程序的需求(通常被視為另一個故障點)。您可以在 Sphinx 源代碼附帶的 README 文件中或通過在線資料找到完整的功能列表。Sphinx Web 站點還列出了已經(jīng)部署了 Sphinx 的若干個項目。
Sphinx 是用 C++ 編寫、用 GNU 編譯器構(gòu)建、支持 64 位支持平臺,并在 Linux、UNIX?、Microsoft? Windows? 和 Mac OS X 上運行。構(gòu)建 Sphinx 十分簡單:下載并解壓縮代碼,然后運行./configure && make && make install命令。
默認(rèn)情況下,Sphinx 實用程序?qū)⒈话惭b到 /usr/local/bin/ 中,并且所有 Sphinx 組件的配置文件都位于 /usr/local/etc/sphinx.conf 中。
Sphinx 有三個組件:索引生成器、搜索引擎和命令行 search 實用程序:
索引生成器被稱為索引器。它將查詢數(shù)據(jù)庫,為結(jié)果的每行中的每列建立索引,并且將每個索引條目綁定到行的主鍵上。 搜索引擎是名為searchd的守護程序。該守護程序?qū)⒔邮账阉髟~和其他參數(shù),快速遍歷一個或多個索引,并返回結(jié)果。如果找到匹配,searchd 將返回一個主鍵數(shù)組。對于這些鍵,應(yīng)用程序可以針對相關(guān)數(shù)據(jù)庫運行查詢來查找包含匹配的完整記錄。Searchd 將在端口 3312 上通過套接字連接與應(yīng)用程序進行通信。 便捷的search實用程序使您可以從命令行構(gòu)造搜索而無需編寫代碼。如果 searchd 返回匹配,則 search 將查詢數(shù)據(jù)庫并顯示匹配集中的行。search 實用程序?qū)τ谡{(diào)試 Sphinx 配置和執(zhí)行臨時搜索十分有用。此外,Sphinx 的作者 Andrew Aksyonoff 和其他貢獻者為 PHP、Perl、C/C++ 和其他編程語言提供了 API。
回頁首
搜索車身零件假定 Body-Parts.com 出售車身零件 —— 擋泥板、鉻、緩沖器等 —— 用于珍貴且值得收藏的汽車。正如在現(xiàn)實世界中,Body Parts 站點的訪問者很可能按制造商(比如保時捷或制造同類零件的第三方制造商)、零件號、產(chǎn)地、車型、年份、條件(二手、全新、翻新)以及描述或者這些屬性的某種組合來搜索零件。
要構(gòu)建 Body Parts 搜索功能,讓我們使用 MySQL V5.0 作為數(shù)據(jù)存儲并使用 Sphinx search 守護程序來提供快速而精確的文本搜索。MySQL V5.0 是一個功能強大的數(shù)據(jù)庫,但是它的增強型全文本搜索功能并不特別豐富。實際上,它僅限于 MyISAM 表 —— 不支持外鍵的一種表格式,因此使用有限。
清單 1 至清單 4 顯示了與此示例相關(guān)的 Body Parts 模式的部分代碼。您將分別看到 Model(清單 1)、Assembly(清單 2)、Inventory(清單 3)和 Schematic(清單 4)表。
Model 表清單 1 中所示的 Model 表十分簡單:label 列將列舉車型的名稱 (“Corvette”);description 使用客戶友好方式進行描述(“兩門跑車;⑴年引入”);而begin_production和end_production分別表示開始生產(chǎn)和結(jié)束生產(chǎn)該車型的年份。由于前述列中的值并不惟一,因此使用一個獨立 ID 表示每四個這樣的元素(label、description、begin_production、end_production),并且是其他表中的外鍵。
清單 1. 車身零件 Model 表下面是 Model 表的一些樣例數(shù)據(jù):
assembly是一個子系統(tǒng),例如汽車上安裝的傳動裝置或所有玻璃。車主使用部件圖及相關(guān)零件列表來查找備件。清單 2 中所示的 Assembly 表也十分簡單:它將把一個惟一 ID 與部件標(biāo)簽和描述關(guān)聯(lián)起來。
清單 2. Assembly 表繼續(xù)示例,下面是 Assembly 表的一些樣例數(shù)據(jù):
Inventory 表是汽車零件的典范列表。零件 —— 例如螺釘或燈泡 —— 可能用于每輛汽車和多個部件中,但是零件只在 Inventory 表中顯示一次。Inventory 表中的每行包含:
使用了惟一的 32 位整數(shù)serialno標(biāo)識行。 字母數(shù)字零件號(此零件號惟一并且可以用作主鍵。但是,由于它可以包含字母數(shù)字字符,因此它不適于與 Sphinx 結(jié)合使用,Sphinx 要求索引的每條記錄都有一個惟一的 32 位整型鍵)。 文本描述。 價格。Inventory 表的規(guī)范如清單 3 中所示:
清單 3. Inventory 表零件的(部分)列表可能如下面所示:
Schematic 表將把零件與部件和車型版本綁定在一起。因此,將使用 Schematic 表來查找組裝 1979 J Class 敞篷車引擎的所有零件。Schematic 表中的每行都有一個惟一 ID,一個引用 Inventory 表行的外鍵,一個標(biāo)識部件的外鍵,以及用于引用 Model 表中特定型號和版本的另一個鍵。各行如清單 4 所示:
清單 4. Schematic 表為了強化表的意圖,下面是 Schematic 中的一張小型行列表:
定義了這些表后,就可以輕松地響應(yīng)很多搜索:
顯示特定型號的所有版本 列出裝配特殊型號和版本所需的所有部件 顯示構(gòu)成特定型號和版本的特殊部件的所有零件但是很多搜索代價較大:
查找所有模型和版本中出現(xiàn)零件號開頭為 “WIN” 的所有零件 查找描述中有 “l(fā)acquer” 或 “paint” 的那些零件 查找描述中有 “black leather” 的所有零件 查找描述中有 “paint” 的所有 2002 J 系列零件這些搜索中的每個搜索都要求使用長篇的JOIN子句或代價高昂的LIKE子句,尤其是在 Inventory 表和 Schematic 表十分大時更是如此。而且,復(fù)雜的文本搜索完全超出了 MySQL 的能力。要搜索大量文本數(shù)據(jù),請考慮構(gòu)建和使用 Sphinx 索引。
回頁首
集成 Sphinx 軟件要應(yīng)用 Sphinx 來解決問題,您必須定義一個或多個數(shù)據(jù)源以及一個或多個索引。
source將標(biāo)識數(shù)據(jù)庫來建立索引,提供驗證信息,并且定義查詢用以構(gòu)造每行。數(shù)據(jù)源可以隨意地標(biāo)識一列或多列作為過濾器,Sphinx 將之稱為組。您將使用組來過濾結(jié)果。例如,單詞描述可能得到 900 個匹配。如果只對特定型號的汽車匹配感興趣,則可以進一步使用型號組進行過濾。
index將要求獲得數(shù)據(jù)源(即一組數(shù)據(jù)行)并定義應(yīng)當(dāng)如何為已從數(shù)據(jù)源中提取出來的數(shù)據(jù)編目。
您將在 sphinx.conf 文件中定義數(shù)據(jù)源和索引。Body Parts 的數(shù)據(jù)源是 MySQL 數(shù)據(jù)庫。清單 5 顯示了名為 catalog 的數(shù)據(jù)源的部分定義 —— 指定連接的數(shù)據(jù)庫以及如何建立連接(主機、套接字、用戶和密碼)的代碼片段。
清單 5. 用于訪問 MySQL 數(shù)據(jù)庫的設(shè)置接下來,創(chuàng)建一個查詢以生成要被索引的行。通常,將創(chuàng)建SELECT子句,可能需要把許多表JOIN在一起才能得到行。但這里存在一個問題:搜索型號和年份必須使用 Assembly 表,但是零件號和零件描述只能在 Inventory 表中找到。為此,Sphinx 必須能夠把搜索結(jié)果與 32 位整型主鍵綁定在一起。
要獲得右側(cè)表單中的數(shù)據(jù),需要創(chuàng)建一個視圖—— MySQL V5 中的新結(jié)構(gòu),它將把來自其他表的列整合到單獨的合成虛擬表中。使用視圖,各類搜索所需的所有數(shù)據(jù)都在一個位置,但是活動數(shù)據(jù)實際上存在于其他表中。清單 6 顯示了定義 Catalog 視圖的 SQL。
清單 6. Catalog 視圖將把數(shù)據(jù)整合到虛擬表中如果用前面所示的表和數(shù)據(jù)創(chuàng)建名為 body_parts 的數(shù)據(jù)庫,則 Catalog 視圖應(yīng)當(dāng)類似以下內(nèi)容:
在視圖中,字段id將指回 Inventory 表中的零件條目。partno和description列是要搜索的主要文本,而assembly和model列用作進一步過濾結(jié)果的組。視圖就緒后,構(gòu)造數(shù)據(jù)源查詢就是小事一樁。清單 7 顯示了 catalog 數(shù)據(jù)源定義的其余部分。
清單 7. 查詢創(chuàng)建待索引的行sql_query必須包括后續(xù)查找需要使用的主鍵,并且它必須包括需要索引和用作組的所有字段。兩個sql_group_column條目將聲明 Assembly 和 Model 可用于過濾結(jié)果。并且 search 實用程序?qū)⑹褂胹ql_query_info來查找匹配記錄。在查詢中,$id被替換為 searchd 返回的每個主鍵。
最后一個配置步驟是構(gòu)建索引。清單 8 顯示了數(shù)據(jù)源 catalog 的索引。
清單 8. 描述 catalog 數(shù)據(jù)源的一個可能的索引第 1 行將指向 sphinx.conf 文件中的指定數(shù)據(jù)源。第 2 行將定義存儲索引數(shù)據(jù)的位置;按照約定,Sphinx 索引將被存儲到 /var/data/sphinx 中。第 3 行將允許索引使用英文詞法。并且第 5 行至第 7 行將告訴索引器只索引含有三個字符或更多字符的那些單詞,并且為每個這樣的字符的子字符串創(chuàng)建中綴索引(為了便于引用,清單 9 顯示了 Body Parts 的完整示例 sphinx.conf 文件)。
清單 9. Body Parts 的示例 sphinx.conf底部的searchd部分將配置 searchd 守護程序本身。該部分中的條目不言自明。query.log 尤為有用:它將在運行時顯示每次搜索并顯示結(jié)果,例如搜索的文檔數(shù)和匹配總數(shù)。
回頁首
構(gòu)建和測試索引您現(xiàn)在已經(jīng)準(zhǔn)備好為 Body Parts 應(yīng)用程序構(gòu)建索引。為此,需要執(zhí)行以下步驟:
鍵入$sudo mkdir -p /var/data/sphinx創(chuàng)建目錄結(jié)構(gòu) /var/data/sphinx 假定 MySQL 正在運行,使用如下所示的代碼運行索引器來創(chuàng)建索引。 清單 10. 創(chuàng)建索引⑴條命令/usr/local/bin/search --config /usr/local/etc/sphinx.conf ENG在零件號中找到了兩個含有ENG的結(jié)果。第二條命令/usr/local/bin/search --config /usr/local/etc/sphinx.conf wind在兩個零件描述中找到了子字符串wind。而第三條命令把結(jié)果限定為model為3的條目。
回頁首
編寫代碼最后,您可以編寫 PHP 代碼來調(diào)用 Sphinx 搜索引擎。Sphinx PHP API 非常小并且易于掌握。清單 12 是一個小型 PHP 應(yīng)用程序,用于調(diào)用 searchd 以得到使用上面所示的最后一條命令得到的相同結(jié)果(“在屬于型號 3 的名稱中找到含有 ‘cylinder’ 的所有零件”)。
清單 12. 從 PHP 調(diào)用 Sphinx 搜索引擎要測試代碼,需要為 Sphinx 創(chuàng)建 log 目錄,啟動 searchd,然后運行 PHP 應(yīng)用程序,如下所示:
清單 13. PHP 應(yīng)用程序輸出為9:匹配的單行的正確主鍵。如果 Sphinx 找到匹配,相關(guān)數(shù)組$result將包含名為results的元素。瀏覽print_r()的輸出以查看返回的其他內(nèi)容。
注意事項:total_found是在索引中找到的匹配總數(shù),而found是返回的結(jié)果數(shù)。這兩者可能不同,因為您可以更改每次返回多少個匹配結(jié)果以及要返回哪批匹配結(jié)果,哪個結(jié)果利于對冗長的結(jié)果列表分頁。請查看 API 調(diào)用SetLimits()。一個分頁示例是用$cl->SetLimits( ( $page - 1 ) * SPAN, SPAN )調(diào)用搜索引擎返回⑴批、第二批、第三批(依此類推)SPAN匹配結(jié)果,這取決于顯示哪個頁面。
回頁首
結(jié)束語Sphinx 還有更多的功能可以利用。我在這里僅僅介紹了最淺顯的一部分,但是您現(xiàn)在有一個可以工作的現(xiàn)實示例作為基石來擴展您的技能。
仔細(xì)研讀隨發(fā)行版附帶的樣例 Sphinx 配置文件 /usr/local/etc/sphinx.conf.dist。該文件中的注釋將說明每個 Sphinx 參數(shù)可以實現(xiàn)的功能;展示如何創(chuàng)建分布式冗余配置;并說明如何繼承基本設(shè)置以避免源代碼及索引中的重復(fù)。Sphinx README 文件還是十分豐富的信息源,包括如何將 Sphinx 直接嵌入 MySQL V5 —— 不需要使用守護程序。
名稱欄目:用PHP構(gòu)建自定義搜索引擎
文章來源:http://www.rwnh.cn/news7/175157.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、網(wǎng)站收錄、云服務(wù)器、App設(shè)計、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容