標籤:高可用性 function search 過濾 contents 商業 api filter 錯誤碼
1.什麼是Sphinx
Sphinx是俄羅斯人Andrew Aksyonoff開發的高效能全文檢索搜尋軟體包,在GPL與商業協議雙許可協議下發行。
全文檢索索引式指以文檔的全部文本資訊作為檢索對象的一種資訊檢索技術。檢索的對象有可能是文章的標題,也有可能是文章的作者,也有可能是文章的摘要或內容。常用於新聞,論壇評論等的模糊查詢。
2.Sphinx的特性
- 高速索引(在新款CPU上,近10MB/S);
- 高速搜尋(2-4G的文本量平均查詢速度不到0.1秒);
- 高可用性(單CPU上最大可支援100GB的文本,100M文檔);
- 提供良好的相關排名;
- 提供文檔摘要產生;
- 提供從Mysql內部的外掛程式式儲存引擎上搜尋;
- 支援布爾,短語,和近義詞查詢;
- 支援單位元組編碼與UTF-8編碼等等。
3.下載coreseek
PS:Coreseek是基於Sphinx開發的,Sphinx只支援mysql,Coreseek支援更多,另外支援中文分詞。
http://www.coreseek.cn/opensource/mmseg/
4.安裝作業系統基礎開發庫以及mysql依賴庫以支援mysql資料來源和xml資料來源
yum install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2-devel expat-devel
(PS:小編使用的linux系統centos5.6測試的,操系作系統版本不同,需安裝不同的庫,具體請點擊)
5.安裝(編譯安裝) 5.1 解壓
tar -zxvf coreseek-3.2.14.tar.gz
cd coreseek-3.2.14
5.2 安裝mmseg
cd mmseg-3.2.14
./bootstrap #輸出的warning資訊可以忽略,但是出現error則需要解決
./configure --prefix=/usr/local/mmseg
make && make install
cd ..
5.3 安裝coreseek
cd csft-3.2.14
sh buildconf.sh #輸出的warning資訊可以忽略,但是出現error則需要解決
./configure --prefix=/usr/local/coreseek --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg/lib/ --with-mysql
make && make install
6.配置測試
cp /usr/local/coreseek/etc/sphinx-min.conf.dist /etc/csft.conf
/usr/local/coreseek/bin/indexer -c /etc/csft.conf
顯示如下
7.配置csft.conf
vim /etc/csft.conf
#配置源source sphinx_t0 #資料庫名_資料表名,每配置一個資料表,都需要寫上一個配置源{ type = mysql #資料庫類型 sql_host = localhost sql_user = root sql_pass = 123123 sql_db = sphinx #指定資料庫 sql_port = 3306 # optional, default is 3306 sql_sock = /tmp/mysql.sock #mysql介面 #從資料庫之中讀取資料的SQL語句設定 #在這裡儘可能不使用where或groupby, #將where與groupby的內容交給sphinx,由sphinx進行條件過濾與groupby效率會更高 #注意:select的欄位必須包括一個唯一主鍵以及要全文檢索索引的欄位(可以有多個)、輸出的欄位。 #where中要用到的欄位也要select出來 #例: #在配置sql語句,可以先寫出一句預計要執行的sql語句,然後根據sphinx規定設定 #select * from t0 where description like ‘%廣州%‘ or name like ‘%s%‘ #=> select id,description,name,age from t0 sql_query = SELECT id, name, age, description,group_id,date_added FROM t0 sql_attr_uint = age #使用sql_attr設定的欄位(搜尋條件),只能作為屬性,使用SphinxClient::SetFilter()進行過濾; #未被設定的欄位,自動作為全文檢索索引的欄位,使用SphinxClient::Query("搜尋字串")進行全文檢索搜尋 #sql_query第一列id需為整數,且被系統使用,無需再設定sql_attr_uint sql_attr_uint = group_id sql_attr_timestamp = date_added #定義不同類型的欄位要用不同的屬性名稱,比如上面的sql_attr_timestamp就是時間戳記類型 #sql_query_info = SELECT * FROM documents WHERE id=$id #命令列查詢時,從資料庫讀取未經處理資料資訊 #在執行sql_query前執行的sql命令, 可以有多條 sql_query_pre = SET NAMES utf8 #執行sql字元編碼}#索引,每一源需要一個索引index sphinx_t0 #索引名字一般與配置源一致{ source = sphinx_t0 #source 關聯源 path = /usr/local/coreseek/var/data/sphinx_t0 #索引檔案存放路徑,每個索引檔案一個 docinfo = extern charset_dictpath = /usr/local/mmseg/etc/ #指明分詞法讀取詞典檔案的位置,當啟用分詞法時,為必填項。在使用LibMMSeg作為分詞 庫時,需要確保詞典檔案uni.lib在指定的目錄下 charset_type = zh_cn.utf-8 #字元編碼}#索引,控制所有索引indexer{ mem_limit = 512M #記憶體}#sphinx守護進程配置 searchd{ port = 9312 #連接埠 log = /usr/local/coreseek/var/log/searchd.log query_log = /usr/local/coreseek/var/log/query.log read_timeout = 5 #逾時 max_children = 30 #最大串連數 pid_file = /usr/local/csft/var/log/searchd.pid #pid檔案路徑 max_matches = 1000 #max_matches最大匹配數,也就是尋找的資料再多也只返回這裡設定的1000條 seamless_rotate = 1 preopen_indexes = 0 unlink_old = 1}
產生索引 /usr/local/coreseek/bin/indexer -c /etc/csft.conf sphinx_t0
啟動 /usr/local/coreseek/bin/searchd -c /etc/csft.conf
至此,Sphinx基本安裝完畢,接下來就是配合PHP使用
8.配合PHP使用
<?php header(‘Content-Type:text/html;charset=utf-8‘); //編碼為utf-8 include ‘sphinxapi.php‘; // 載入Sphinx API,網上下載 $list= array(); if(!empty($_POST)){ $sc = new SphinxClient(); // 執行個體化Api $sc->setServer(‘192.168.1.108‘, 9312); // 設定服務端,第一個參數sphinx伺服器位址,第二個sphinx監聽連接埠 $res = $sc->query($_POST[‘key‘], ‘sphinx_t0‘); // 執行查詢,第一個參數查詢的關鍵字,第二個查詢的索引名稱,mysql索引名稱(這個也是在設定檔中定義的),多個索引名稱以,分開,也可以用*表示所有索引。 // print_r($sc); print_r($res);exit; } ?><form action="" method="post"><input type="text" name="key" /><input type="submit" value="提交" /></form>
?>
注意:如果輸出的結果是空白,可列印print_r($sc),查看錯誤碼。
錯誤碼10060:伺服器防火牆沒有開放9312連接埠,直接關閉防火牆即可 service iptables stop.
錯誤碼10061:可能是索引沒有產生成功,構造好詞典,重建索引即可。
9.更新詞典及詞典的構造
9.1 從搜狗IME官網下載所需要的詞庫
9.2 用深藍詞庫轉換器將下載好的詞庫轉換成txt檔案,深藍詞庫google 深藍詞庫github
9.3 用PHP代碼將檔案轉換成符合詞典規則的txt檔案(注意:新產生的檔案內容words_new.txt與原檔案unigram.txt內容沒有交集,因此可將新檔案內容追加到unigram.txt,執行命令 cat /usr/local/mmseg/etc/words_new.txt >> /usr/local/mmseg/etc/unigram.txt)
<?phpini_set(‘display_errors‘, ‘On‘);error_reporting(E_ALL);date_default_timezone_set (‘Asia/Shanghai‘);set_time_limit(0);$buffer = ini_get(‘output_buffering‘);if($buffer){ ob_end_flush();}//注意檔案的編碼格式是utf8echo ‘處理新詞庫...‘.PHP_EOL; //PHP_EOL windwos相當於‘\r\n‘,unix\linux相當於‘\n‘flush();$filename = "words.txt";$handle = fopen ($filename, "r");$content = fread ($handle, filesize ($filename));fclose ($handle);$content = trim($content);$arr1 = explode( "\r\n" ,$content );// print_r($arr1);exit;$arr1 = array_flip(array_flip($arr1)); //反轉數組的索引值,剔除重複的值foreach($arr1 as $key=>$value){ $value = dealchinese($value); if(!empty($value)){ $arr1[$key] = $value; }else{ unset($arr1[$key]); }}// print_r($arr1);exit;echo ‘處理原來詞庫...‘.PHP_EOL;flush();$filename2 = "unigram.txt";$handle2 = fopen ($filename2, "r");$content2 = fread ($handle2, filesize ($filename2));fclose ($handle2);$content2 = dealchinese($content2,"\r\n");$arr2 = explode( "\r\n" ,$content2 );echo ‘刪除相同詞條...‘.PHP_EOL;flush();$array_diff = array_diff($arr1,$arr2);echo ‘格式化詞庫...‘.PHP_EOL;flush();$words=‘‘;foreach($array_diff as $k => $word){ $words .= $word."\t1".PHP_EOL."x:1".PHP_EOL;}//echo $words;file_put_contents(‘words_new.txt‘,$words,FILE_APPEND); //寫入檔案echo ‘done!‘;function dealChinese($str, $join=‘‘){ preg_match_all(‘/[\x{4e00}-\x{9fff}]+/u‘, $str, $matches); //將中文字元全部匹配出來 $str = join($join, $matches[0]); //從匹配結果中重新組合 return $str;}?>
9.4 重新整理中文分詞
cd /usr/local/mmseg/bin
./mmseg -u ../etc/unigram.txt 產生一個名為unigram.txt.uni的檔案
cd ..
cd etc
mv unigram.txt.uni uni.lib 將該檔案名稱改為uni.lib,完成詞典的構造
10.重建索引、重啟服務
/usr/local/coreseek/bin/searchd -c /etc/csft.conf --stop #停止searchd服務
/usr/local/coreseek/bin/indexer -c /etc/csft.conf --all -rotate #重生所有索引
/usr/local/coreseek/bin/searchd -c /etc/csft.conf #啟動searchd服務
注意:產生索引的過程中如果出現segmentation fault錯誤,可從以下三方面排查
情況一、uni.lib檔案路徑錯誤或找不到該檔案
情況二、unigram.txt檔案過大,一般不超過20W條資料
情況三、使用記事本等編輯器編輯過unigram.txt檔案,造成詞典檔案格式不正確(最好使用notepad++開啟)
情況四、unigram.txt檔案內容排版不統一,檔案尾部換行太多(經測試,最多隻能空一行)。
至此,OVER
Sphinx安裝流程及配合PHP使用經驗