LAMP+Coreseek+sphinx構建中文檢索引擎

什麼是Sphinx/Coreseek

Sphinx是一個在GPLv2下分發的全文檢索引擎;Coreseek是一個可供企業使用的、基於Sphinx(可獨立於Sphinx原始版本運行)的中文全文檢索引擎,按照GPLv2協議發行,商業使用(例如, 嵌入到其他程序中)需要聯繫我們以獲得商業授權。

一般而言,Sphinx是一個獨立的全文搜索引擎;而Coreseek是一個支持中文的全文搜索引擎,意圖爲其他應用提供高速、低空間佔用、高結果相關度的中文全文搜索能力。Sphinx/Coreseek可以非常容易的與SQL數據庫和腳本語言集成。

當前系統內置MySQLPostgreSQL 數據庫數據源的支持,也支持從管道標準輸入讀取入特定格式的XML數據。通過修改源代碼,用戶可以自行增加新的數據源(例如:其他類型的DBMS的原生支持)。在最新的版本中,用戶還可以使用Python腳本作爲數據源來獲取任何已知世界和未知世界的數據,這極大的擴展了數據源的來源。

搜索API支持PHPPythonPerlRudyJava,並且也可以用作MySQL存儲引擎。搜索API非常簡單,可以在若干個小時之內移植到新的語言上。

Sphinx SQL PhraseIndex的縮寫,但不幸的和CMUSphinx項目重名。

Coreseek  http://www.coreseek.cn Sphinx在中國地區的用戶提供支持服務.   

Sphinx  http://sphinxsearch.com/               

 

Sphinx/Coreseek 的特性

  • 高速的建立索引(在當代CPU上,峯值性能可達到10MB/);

  • 高性能的搜索(2 – 4GB 的文本數據上,平均每次檢索響應時間小於0.1);

  • 可處理海量數據(目前已知可以處理超過100GB的文本數據, 在單一CPU的系統上可處理100 M 文檔);

  • 提供了優秀的相關度算法,基於短語相似度和統計(BM25)的複合Ranking方法;

  • 支持分佈式搜索;

  • 提供文檔片段(摘要以及高亮)生成功能;

  • 可作爲MySQL的存儲引擎提供搜索服務;

  • 支持布爾、短語、詞語相似度等多種檢索模式;

  • 文檔支持多個全文檢索字段(缺省配置下,最大不超過32);

  • 文檔支持多個額外的屬性信息(例如:分組信息,時間戳等);

  • 停止詞查詢;

  • 支持單一字節編碼和UTF-8編碼,以及對GBKBIG5的完善支持;

  • 支持英語、俄語詞詞幹化和Soundex,以便進行詞形學處理;

  • 原生的MySQL支持(同時支持MyISAM InnoDB );

  • 原生的PostgreSQL支持;

  • 支持直接模擬爲MySQL服務端運行;

  • 支持MMSeg分詞引擎,用戶可自定義詞典;

  • Python數據源支持,得以獲取任何已知世界和未知世界的數據.

目前,Sphinx/Coreseek的發佈包包括如下軟件:

  • indexer: 用於創建全文索引;

  • search: 一個簡單的命令行(CLI) 的測試程序,用於測試全文索引;

  • searchd: 一個守護進程,其他軟件可以通過這個守護進程進行全文檢索;

  • sphinxapi: 一系列searchd 的客戶端API 庫,用於流行的Web腳本開發語言(PHP, Python, Perl, Ruby, Java).

  • spelldump: 一個簡單的命令行工具,用於從 ispell  MySpell (OpenOffice內置綁定) 格式的字典中提取詞條。當使用 wordforms 時可用這些詞條對索引進行定製.

  • indextool: 工具程序,用來轉儲關於索引的多項調試信息。此工具是從版本Coreseek 3.1(Sphinx 0.9.9-rc2)開始加入的。

  • mmseg: 工具程序和庫,Coreseek用於提供中文分詞和詞典處理。

安裝前準備環境

yum install make gcc g++ gcc-c++ libtool make mysql-devel libxml2-devel expat-devel 

官網參考地址:http://www.coreseek.cn/products/products-install/install_on_bsd_linux/RHEL5-5/


來到官網http://www.coreseek.com/下載Coreseek 3.2.14穩定版,解壓進入目錄。

# tar xf coreseek-3.2.14.tar.gz

# cd coreseek-3.2.14

配置語言支持中文

# export LANG="zh_CN.UTF-8"

# export LC_ALL="zh_CN.UTF-8"

# cat testpack/var/test/test.xml

wKiom1R-i4bgy4L2AAGxpagGNaw469.jpg

安裝coreseek開發的mmseg,爲coreseek提供中文分詞功能

# cd mmseg-3.2.14/

# ./bootstrap

# ./configure --prefix=/usr/local/mmseg3

# make && make install

中文分詞測試

# /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc src/t1.txt

 

中文/x /x /x 測試/x

中國人/x 上海市/x

 

Word Splite took: 0 ms.

安裝coreseek

# cd csft-3.2.14/

# sh buildconf.sh

./configure --prefix=/alidata/server/sphinx/coreseek --without-python --without-unixodbc --with-mmseg --with-mmseg-includes=/alidata/server/sphinx/mmseg3/include/mmseg --with-mmseg-libs=/alidata/server/sphinx/mmseg3/lib/ --with-mysql=/alidata/server/mysql  --with-mysql-includes=/alidata/server/mysql/include/

# make && make install

測試是否可以正常運行

# /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx-min.conf.dist

wKioL1R-jGuw-AWdAAFTJpw38mI702.jpg

csft-4.0版顯示:ERROR: nothing to do.


coreseek中文全文檢索測試

# cd testpack/

# /usr/local/coreseek/bin/indexer -c etc/csft.conf

wKiom1R-jEfDtn-DAAEXq729j_8678.jpg

索引全部數據

# /usr/local/coreseek/bin/indexer -c etc/csft.conf -all

wKioL1R-jcrxJ2dNAAG8p9tFa-I285.jpg

索引指定數據

# /usr/local/coreseek/bin/indexer -c etc/csft.conf xml

wKiom1R-kE2BkFSPAAGH6upCW9M497.jpg

測試搜索

# /usr/local/coreseek/bin/search -c etc/csft.conf

wKiom1R-kM_gwWq9AAFuX0pLqho609.jpg

測試搜索關鍵詞

# /usr/local/coreseek/bin/search -c etc/csft.conf -a hello歡迎來到北京清華大學

wKiom1R-kQ_z2PkyAAFde5WUkvA847.jpg

開啓搜索服務

# /usr/local/coreseek/bin/searchd -c etc/csft.confwKioL1R-kcbxxTyPAAGDtENOrVE686.jpg

# 如要已啓動服務,要更新索引,請使用 /usr/local/coreseek/bin/indexer-c etc/csft.conf --all --rotate

# 如要停止搜索服務,請使用 /usr/local/coreseek/bin/searchd-c etc/csft.conf --stop

 

然後,請參考csft-3.2.14api目錄中的相關文件,使用PHPPythonRubyJava來測試搜索服務;也可以前往< ahref="/products-install/step_by_step/">搜索服務建立三步曲,查看第三步使用PHP測試。

 

通過以上步驟,coreseek已經安裝測試完成,可以提供正常的xml數據源索引以及提供對應的搜索服務了,下一步工作,請查看手冊,準備好mysql數據信息,以及進行mysql數據源的測試,並在您的應用中調用搜索服務;mysql數據源的配置可參考testpack/etc/csft_mysql.conf文件


官方文檔地址:http://www.coreseek.cn/docs/coreseek_3.2-sphinx_0.9.9.html

快速安裝地址:http://www.coreseek.cn/product_install/install_on_bsd_linux/#mysql

在實現以上功能之後,即可開始下面的實驗。


LAMP+Coreseek+sphinx構建中文檢索引擎

安裝好LAMP環境,並將它們啓動(),在前面的文章中都有講到。


1、  先給數據庫插入一些數據,用於測試,在解壓coreseek源碼包後可以在/coreseek-4.1-beta/testpack/var/test/找到.sql的數據庫腳本文件,導入數據庫即可。

 

2、  安裝PHPsphinx擴展

可以在這裏(http://pecl.php.net/package/sphinx)找到sphinxphp擴展源碼,注意,使用phpizeconfigure的時候可能會要求要安裝libsphinxclient,它在coreseek-4.1-beta/csft-4.1/api/libsphinxclient/裏面能找到,編譯安裝它以後就可以configuremake,生成動態so文件了。

 

3、  給服務提供配置文件 (源碼目錄下有樣例:  /coreseek-4.1-beta/testpack/etc/csft_mysql.conf

#源定義

source study

{

        type                                    = mysql


        sql_host                                = localhost

        sql_user                                = root

        sql_pass                                =

        sql_db                                  = test

        sql_port                                = 3306

        sql_query_pre                   = SET NAMES utf8


        sql_query                               = select id,title,content,group_id from documents;

// 這裏使用select 將想要被用於檢索的索引字段查出來,緩存於Sphinx服務器中,sql_query第一列id需爲整數,titlecontent作爲字符串/文本字段,被全文索引

        sql_query_info                  = SELECT * FROM documents where id=$id  

 #僅被命令行搜索所用,用來獲取和顯示文檔信息,目前僅對MySQL有效,且僅用於調試目的。此查詢爲每個文檔ID獲取CLI搜索工具要顯示的文檔信息。它需要包含$id宏,以此來對應到查詢的文檔的ID

}


#index定義

index study

{

        source                  = study             #對應的source名稱

        path                    = /usr/local/coreseek/var/data/study

        docinfo                 = extern

        mlock                   = 0

        morphology              = none   //不使用任何詞形處理器

        min_word_len            = 1      //最小索引詞長度。可選選項,默認爲1(索引任何詞

        html_strip                              = 0

        charset_dictpath = /usr/local/mmseg3/etc/    //設置中文分詞詞典所在的目錄

        #charset_dictpath = etc/        

        charset_type            = zh_cn.utf-8

}

source mysql

{

        type                                    = mysql


        sql_host                                = localhost

        sql_user                                = root

        sql_pass                                =

        sql_db                                  = tuchao

        sql_port                                = 3306

        sql_query_pre                   = SET NAMES utf8


        sql_query                               = SELECT id, title, abstract FROM ic_video

                                                                                     

        sql_query_info                  = SELECT * FROM ic_video where id=$id  

}



index mysql

{

        source                  = mysql            

        path                    = /usr/local/coreseek/var/data/mysql

        docinfo                 = extern

        mlock                   = 0

        morphology              = none

        min_word_len            = 1

        html_strip                              = 0

        charset_dictpath = /usr/local/mmseg3/etc/  

        #charset_dictpath = etc/   

        charset_type            = zh_cn.utf-8

}

source qupeiyin

{

        type                                    = mysql


        sql_host                                = localhost

        sql_user                                = root

        sql_pass                                =

        sql_db                                  = tuchao2

        sql_port                                = 3306

        sql_query_pre                   = SET NAMES utf8


        sql_query                               = SELECT id, title, description FROM course

                                                                                    

        sql_query_info                  = SELECT * FROM course where id=$id  

}


index qupeiyin

{

        source                  = qupeiyin  

        path                    = /usr/local/coreseek/var/data/qupeiyin

        docinfo                 = extern

        mlock                   = 0

        morphology              = none

        min_word_len            = 1

        html_strip                              = 0

        charset_dictpath = /usr/local/mmseg3/etc/  

        #charset_dictpath = etc/  

        charset_type            = zh_cn.utf-8

}


#全局index定義

indexer

{

        mem_limit                       = 128M    //索引過程內存限制,indexer不會超越的強制內存限制,設置太低會影響索引速度,一般爲256M~1024M,最大限制是2048M.

}


#searchd服務定義

searchd

{

    listen                  =   9312

        read_timeout            = 5  //網絡客戶端請求的讀超時時間, searchd 強制關閉在此時間內未能成功發出查詢的客戶端連接。

        max_children            = 30  //子進程的最大數量,任何時候不可能有比此設置值更多的搜索同時運行。當達到限制時,新的輸入客戶端會被用臨時失敗(SEARCH_RETRY)狀態碼駁回;

        max_matches                     = 1000   //爲每個索引所保持並返回給客戶端的匹配數目的最大值

        seamless_rotate         = 1                          //啓用無縫輪換,數據輪換時不暫停搜索服務。

        preopen_indexes         = 0

        unlink_old                      = 1    //索引輪換成功之後,是否刪除以.old爲擴展名的索引拷貝。可選選項,默認爲1(刪除這些索引拷貝)。

        pid_file = /usr/local/coreseek/var/log/searchd_mysql.pid

        log = /usr/local/coreseek/var/log/searchd_mysql.log

        query_log = /usr/local/coreseek/var/log/query_mysql.log

}

在寫配置文件的時候,sourece名稱可以與index名稱不一樣,但是path後的名稱一定要和index定義的名稱一致。

4、提供服務啓動腳本


#!/bin/bash

# searchd - this script start and stop the searchd daemon

#

# chkconfig - 85 20

# description: 

#

# processname: searchd

# config:  /usr/local/coreseek/etc/csft_mysql.conf

. /etc/rc.d/init.d/functions


searchd="/usr/local/coreseek/bin/searchd"

prog=$(basename $searchd)

conf_file="/usr/local/coreseek/etc/csft_mysql.conf"

lockfile="/var/lock/subsys/searchd"


start() {

    [ -e $lockfile ] && echo "searchd is already start" && exit 0

    [ -x $searchd ] || exit 1

    [ -f $conf_file ] || exit 2

    echo -n "Starting $prog:"

    daemon $searchd -c $conf_file

    retval=$?

    echo

    if [ $retval -eq 0 ]; then

       touch $lockfile

    else

        echo "$prog is starting failed"

    fi

        return $retval

}

stop() {

    echo -n $"Stopping $prog:"

    killproc $prog -QUIT

    retval=$?

    echo

    if [ $retval -eq 0 ]; then

       rm -rf $lockfile

    fi

        return $retval

}


restart() {

stop

sleep 1

start

}


indexer() {

/usr/local/coreseek/bin/indexer -c $conf_file --all


}


case "$1" in

        start)

             start

             ;;

        stop)

            stop

            ;;

        restart)

            restart

            ;;

        indexer)

           indexer

            ;;

        *)

           echo "Usage:$0 {start|stop|restart|indexer}"

           exit 2

esac


5、  重建全部索引

# /etc/init.d/searchd indexer

wKioL1SVGm_C--PGAAGBaCYcCW8559.jpg

6、  啓動searchd服務

# service searchd start

wKiom1SVGfCCWZAkAAG2-9Ntc5o667.jpg


7、  提供PHP測試程序

<?php

$s = new SphinxClient;

$s->setServer("localhost", 9312);

$s->setArrayResult(true);

$s->setSelect();

$s->setMatchMode(SPH_MATCH_ALL);

//SPH_MATCH_ALL這個檢索方法表示只顯示匹配到的數據ID,並進行分詞。SPH_MATCH_ANY表示先將搜索的內容進行分詞,輸出每個分詞匹配到的數據ID

$result1 = $s->query('喬布斯','mysql');

$result2 = $s->query('搞笑','qupeiyin');

$result3 = $s->query('Google','study');

print_r($result1);

print_r($result2);

print_r($result3);

?>


8、測試服務

    我可以在httpd服務器指定的目錄下創建一個test.php拷貝以上代碼,根據自己的數據庫數據做更改後保存。

這一句我要講下: $result1 = $s->query('喬布斯','mysql');  “喬布斯是搜索的關鍵詞,後面的’mysql ’對應的是定義在csft_mysql.conf中的索引名稱。表示從哪個索引中找

 

以下是用瀏覽器訪問test.php返回的結果:

wKioL1SVHA3zks_OAALbYkfToLo666.jpg

    首先返回結果是在mysql索引中搜索關鍵詞喬布斯的,可以看到在id=>38 id=>39  有匹配到,而且對蒐集內容進行了分詞。

[matches] => Array ( [0] => Array ([id] => 38 [weight] => 6 [attrs] => Array ( ) ) [1] => Array ( [id]=> 39 [weight] => 3 [attrs] => Array ( ) ) ) [total] => 2 [total_found]=> 2 [time] => 0.002 [words] => Array ( [] =>Array ( [docs] => 2 [hits] => 3 ) [] => Array ([docs] => 2 [hits] => 3 ) [] => Array ( [docs] => 2 [hits] => 3 ) ) )

 

我們上MySQL服務器查找對應ID來驗證:

wKiom1SVG6yCXgugAAQlK5NWBiE542.jpg


    我們再分析後續的輸出結果,在qupeiyin索引中搜索搞笑關鍵詞,這裏可以看到在id=>29 id=>518  有匹配到.

Array ( [error] => [warning] =>[status] => 0 [fields] => Array ( [0] => title [1] => description )[attrs] => Array ( ) [matches] => Array ( [0] => Array ( [id] => 29 [weight] => 1 [attrs] => Array () ) [1] => Array ( [id] => 518 [weight]=> 1 [attrs] => Array ( ) ) ) [total] => 2 [total_found] => 2[time] => 0.002 [words] => Array ( [搞笑] => Array ([docs] => 2 [hits] => 2 ) ) )

 

我們再來到數據庫驗證:

wKiom1SVHAni20lhAAI7IldQj_M848.jpg


wKioL1SVHLyAsyxwAAKuxXjR0SA840.jpg


第三個輸出也是可以找到對應的數據的,筆者就不上圖了,由此可以看出,在對應的ID號確實能找到匹配的數據。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章