Sphinx安裝流程及配合PHP使用經驗

1.什麼是Sphinx

Sphinx是俄羅斯人Andrew Aksyonoff開發的高性能全文搜索軟件包,在GPL與商業協議雙許可協議下發行。php

全文檢索式指以文檔的所有文本信息做爲檢索對象的一種信息檢索技術。檢索的對象有多是文章的標題,也有多是文章的做者,也有多是文章的摘要或內容。經常使用於新聞,論壇評論等的模糊查詢。html

2.Sphinx的特性

  • 高速索引(在新款CPU上,近10MB/S);
  • 高速搜索(2-4G的文本量平均查詢速度不到0.1秒);
  • 高可用性(單CPU上最大可支持100GB的文本,100M文檔);
  • 提供良好的相關性排名;
  • 提供文檔摘要生成;
  • 提供從Mysql內部的插件式存儲引擎上搜索;
  • 支持布爾,短語,和近義詞查詢;
  • 支持單字節編碼與UTF-8編碼等等。

3.下載coreseek

  PS:Coreseek是基於Sphinx開發的,Sphinx只支持mysql,Coreseek支持更多,另外支持中文分詞。mysql

  http://www.coreseek.cn/opensource/mmseg/linux

4.安裝操做系統基礎開發庫以及mysql依賴庫以支持mysql數據源和xml數據源

  yum install make gcc g++ gcc-c++ libtool  autoconf automake imake mysql-devel libxml2-devel expat-develc++

  (PS:小編使用的linux系統centos5.6測試的,操系做系統版本不一樣,需安裝不一樣的庫,具體請點擊)git

5.安裝(編譯安裝)

  5.1 解壓

  tar -zxvf coreseek-3.2.14.tar.gzgithub

  cd coreseek-3.2.14sql

  5.2 安裝mmseg

  cd mmseg-3.2.14數據庫

  ./bootstrap  #輸出的warning信息能夠忽略,可是出現error則須要解決bootstrap

  ./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:多是索引沒有生成成功,構造好詞典,從新生成索引或者searchd服務沒有開啓。  

9.更新詞典及詞典的構造

  9.1 從搜狗輸入法官網下載所須要的詞庫

  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

<?php
ini_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();
}
//注意文件的編碼格式是utf8
echo '處理新詞庫...'.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錯誤,可從如下三方面排查

  狀況1、uni.lib文件路徑錯誤或找不到該文件

  狀況2、unigram.txt文件過大,通常不超過20W條數據

  狀況3、使用記事本等編輯器編輯過unigram.txt文件,形成詞典文件格式不正確(最好使用notepad++打開)

  狀況4、unigram.txt文件內容排版不統一,文件尾部換行太多(經測試,最多隻能空一行)。

至此,OVER

相關文章
相關標籤/搜索