顯示具有 sphinx 標籤的文章。 顯示所有文章
顯示具有 sphinx 標籤的文章。 顯示所有文章

2010年3月26日 星期五

sphinx for freebsd 完整安裝流程 (4)

接下來,為了要讓 sphinx 可以支援中文欄位的精確搜尋,我們要使用之前文章所安裝好的 sphinxse,首先我們先將我們要索引的資料放進資料庫,別忘了要有一個 id 的欄位,接下來設定 sphinx.conf 的檔案內容。
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#
source src_ticket
{
    type                  = mysql          # 資料庫類型
    sql_host              = localhost      # 資料庫位置
    sql_user              = user           # 資料庫使用者
    sql_pass              = pass           # 資料庫密碼
    sql_db                = test           # 資料庫名稱
    sql_port              = 3306           # optional, default is 3306
    sql_query_pre         = set names utf8 # Query 前會先執行的語法
    sql_query             = \              # Query Index 資料
        SELECT  id, serial, category, enable, retail_price, progname, lastmodified \
        FROM test_table
    sql_attr_uint         = retail_price   # 檢索時不會檢索此欄位,可用於 filter, sort
    sql_attr_timestamp    = lastmodified   # 檢索時不會檢索此欄位,可用於 filter, sort
    sql_query_info        = SELECT item,progname FROM test_table WHERE id=$id # 使用內建 search 程序,自動取得完整資料的語法
}
index ix_ticket
{
    source                = src_ticket                           # source 的名稱
    path                  = /usr/local/sphinx/var/data/ix_ticket # index放置的路徑以及索引名稱的前置詞
    docinfo               = extern
    charset_type          = utf-8                                # 編碼
    chinese_dictionary    = /usr/local/sphinx/etc/xdict          # 分詞檔完整路徑
}
indexer
{
    mem_limit             = 256M
}
searchd
{
    port                  = 9312
    log                   = /usr/local/sphinx/var/log/searchd.log
    query_log             = /usr/local/sphinx/var/log/query.log
    read_timeout          = 5
    max_children          = 30
    pid_file              = /usr/local/sphinx/var/log/searchd.pid
    max_matches           = 1000
    seamless_rotate       = 1
    preopen_indexes       = 0
    unlink_old            = 1
}
依照 config 建立 index
# 建立索引
/usr/local/sphinx/bin/indexer --all
# 輸出結果
Sphinx 0.9.9-release (r2117)
Copyright (c) 2001-2009, Andrew Aksyonoff

using config file '/usr/local/sphinx/etc/sphinx.conf'...
indexing index 'ix_ticket'...
collected 3694 docs, 0.2 MB
sorted 0.0 Mhits, 100.0% done
total 3694 docs, 199207 bytes
total 0.060 sec, 3292242 bytes/sec, 61049.77 docs/sec
total 2 reads, 0.000 sec, 150.1 kb/call avg, 0.4 msec/call avg
total 7 writes, 0.002 sec, 106.9 kb/call avg, 0.3 msec/call avg
# 啟動 searchd
/usr/local/sphinx/bin/searchd
當啟動 searchd 之後,我們就可以在資料庫建用 sphinxse ,語法如下
-- 建立時,資料庫主機會即時連線 localhost:9312 是否正常
-- ix_ticket 為 index 的名稱,table name 可以隨便取,但在 localhost:9312 後面的 index name 一定要對應到 sphinx.conf 的設定
CREATE TABLE ix_ticket
(
    id          INTEGER UNSIGNED NOT NULL,
    weight      INTEGER NOT NULL,
    query       VARCHAR(3072) NOT NULL,
    group_id    INTEGER,
    INDEX(query)
) ENGINE=SPHINX CONNECTION="sphinx://localhost:9312/ix_ticket";
建立好,我們就可以來試試是否運作正常,下面是我測試的範例
<?php
// 文字比較好 debug
header("Content-type: text/plain; charset=utf-8;");
// 設定 get 值,並判斷是否為 utf-8 的型態
$q = $_GET['q'];
$q = (!mb_check_encoding($q,"UTF-8")) ? iconv('cp950', 'utf-8', $q) : $q;
// 數據庫連線
$connection = mysql_connect('localhost', 'user', 'name');
mysql_select_db('test', $connection);
mysql_query("set names utf8", $connection);
/**
 * 這邊是欄位搜尋的範例
 * 檢查 progname 的欄位是否有此關鍵字
 **/
$sql = "select * from t1, test_table m1 where t1.id=m1.id and query = '@progname $q; mode=extended'";
echo "\n";
echo "SQL: ".$sql."\n";
echo "\n";
$rlt = mysql_query($sql, $connection);
while($row = mysql_fetch_assoc($rlt))
{
    echo $row['id']."\t";
    echo $row['serial']."\t";
    echo $row['progname']."\t";
    echo $row['retail_price']."\n";
}
mysql_free_result($rlt);
?>
測試結束,接下來就要開始試試資料庫有 300 萬筆時,是否會影響到搜尋的效能

2010年3月25日 星期四

sphinx for freebsd 完整安裝流程 (3)

接下來就是我們的重頭戲了,安裝mysql51-server以及sphinx-for-chinese
下載網址如下:
sphinx(原始網站)
sphinx-for-chinese
mysql51-server(要下載source code)

第 1 步,先解壓縮 2 個壓縮檔
tar -zxvf sphinx-for-chinese-0.9.9-r2117.tar.gz
tar -zxvf mysql-5.1.45.tar.gz

第 2 步,安裝sphinxse engine,參閱 MySQL storage engine (SphinxSE)
# copy storage to mysql directory
cp -R sphinx-for-chinese-0.9.9-r2117/mysqlse mysql-5.1.45/storage/sphinx
# run script
cd mysql-5.1.45/
sh BUILD/autorun.sh
# configure
./configure \
--with-plugins=sphinx \
--with-low-memory
make
make install
第 3 步,安裝完後,我們也是要檢查MySQL有沒有成功的將 sphinx engine type 安裝進去
# adduser
pw user add mysql
# 初始化資料庫
/usr/local/bin/mysql_install_db
# 更改權限
chown -R mysql:mysql /usr/local/var
# 啟動 mysql
/usr/local/share/mysql/mysql.server start
# 先建立 mysql root 的密碼(記得要先啟動 mysql)
mysqladmin -u root password '000000'

# 登入 mysql
mysql -u root -p

# 查詢 engine type
show engines;

mysql< show engines;
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
| Engine     | Support | Comment                                                   | Transactions | XA   | Savepoints |
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
| CSV        | YES     | CSV storage engine                                        | NO           | NO   | NO         |
| SPHINX     | YES     | Sphinx storage engine 0.9.9                               | NO           | NO   | NO         |
| MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables | NO           | NO   | NO         |
| MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance    | NO           | NO   | NO         |
| MRG_MYISAM | YES     | Collection of identical MyISAM tables                     | NO           | NO   | NO         |
+------------+---------+-----------------------------------------------------------+--------------+------+------------+
5 rows in set (0.00 sec)
接下來要建立 sphinx 的 table ,這時候 phpmyadmin 就用的上了,執行下面的 SQL 語法(要先將 index 建好)
CREATE TABLE t1
(
    id          INTEGER UNSIGNED NOT NULL,
    weight      INTEGER NOT NULL,
    query       VARCHAR(3072) NOT NULL,
    group_id    INTEGER,
    INDEX(query)
) ENGINE=SPHINX CONNECTION="sphinx://localhost:9312/test";
-- sphinx://[hostname]:[port]/[index] 

sphinx for freebsd 完整安裝流程 (2)

因為之後測試的時候需要用到 PHP 以及 phpMyAdmin 所以也必需安裝這些套件 首先,先安裝MySQL51-client的套件,因為直接安裝phpMyAdmin,如果沒有偵測到mysql-client,會預設安裝mysql50-client,而sphinxse在mysql50的版本下,安裝會有較多的問題,所以我們就先安裝mysql51-client。
cd /usr/ports/databases/mysql51-client/
make install clean
安裝完後,再安裝 apache 2.2 版
cd /usr/ports/www/apache22/
make install clean
接下來是PHP,但記得要安裝 for apache 的 module
cd /usr/ports/databases/phpmyadmin/
# 選擇安裝 apache 的 module
make config
make install clean
最後,在apache的config檔上加上phpmyadmin的設定
vi /usr/local/etc/apache22/httpd.conf
# 大約在 162 行,尋找下面的設定
#
#    AllowOverride None
#    Order deny,allow
#    Deny from all
#
# 在這段設定後面加上一些設定
Alias /phpmyadmin/ "/usr/local/www/phpMyAdmin/"

    Options none
    AllowOverride Limit
    Order Deny,Allow
    Deny from all
    Allow from all

這樣就算安裝好apache,php,phpmyadmin了。

sphinx for freebsd 完整安裝流程 (1)

首先,必需建置 FreeBSD 的系統環境,個人是採用 VM 的方式建置, FreeBSD 的版本為 FreeBSD 8.0-RELEASE 安裝完基本的 BSD 環境後,當然別忘了要先更新一下 ports ,我採用的做法是使用 CTM 如果你的系裝裝完後 /usr/ports/ 的目錄下已經有目錄或檔案的時候,就要先把所有的檔案跟目錄刪除,留下一個空的 /usr/ports/ 目錄。 再來就是要跟 ctm 相關的檔案先 download 到機器上面
# /tmp 的目錄空間要檢查一下,大概需要 200~300 MB 的空間
cd /tmp
# 選擇一個離你最近的 mirror site ,帳號輸入 ftp 就可以直接登入
ftp ftp6.tw.freebsd.org
# 進入 CTM 的目錄
cd pub/FreeBSD/CTM/ports-cur
# 接下來可以用 ls 的指令檢查一下最後的版本號,我目前看到的是 ports-cur.82*
prompt
mget ports-cur.82*
# 結束後就是完成所有的下載動作,離開 ftp mode
by
當下載完檔案後,將 ports-cur.8200.gz 這個檔案刪除,如果你下載的是 81* ,就請將 ports-cur.8100.gz 刪除,以此類推。 刪除後切換至 /usr/ports 的目錄下
# 開始更新 ports free,請注意你更新的版本
cd /usr/ports/
ctm -v /tmp/ports-cur.82*
至此,PORTS已更新完成 順便更新一下 make.conf 的檔案,讓安裝時下載的速度更順暢,這邊是參考Zeroplex生活隨筆的文章
# 開啟
vi /etc/make.conf

# 檔案內容

# for make install
MASTER_SITE_BACKUP?= \
ftp://ftp6.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp11.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/

MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}
MASTER_SORT_REGEX=      \.tw/ \.tw\. \.edu/ \.edu\.
FETCH_CMD=fetch -U -A -P

WITHOUT_X11=yes

MAKE_JOBS_NUMBER=3

# for cvsup make update

SUP_UPDATE=yes
SUP=            /usr/bin/csup
SUPFLAGS=       -g -L 2
SUPHOST=        cvsup2.tw.FreeBSD.org
SUPFILE=        /usr/share/examples/cvsup/standard-supfile
PORTSSUPFILE=   /usr/share/examples/cvsup/ports-supfile
DOCSUPFILE=     /usr/share/examples/cvsup/doc-supfile

2010年3月22日 星期一

sphinx for chinese 讓 sphinx 加入中文斷詞

上星期測試完 sphinx 後,讓它極快的速度所折服,但是在應用搜尋時就碰到了中國人都會碰到的問題......

沒有中文分詞的搜尋結果似乎有這麼一點點不太符合需求,展轉之間便 google 了市面上較為人知的 2 套支援中文分詞的 sphinx。分別是

sphinx-for-chiness 以及 coreseek

經過一連串的測試後,sphinx-for-chinese比較走原創者的路線,只是在功能中加入支援中文分詞的功能,coressek則是大改之後的版本,相關的設定檔名稱以及指令都有做變動,所以在考慮之後決定使用 sphinx-for-chinese繼續我的搜尋測試之路。

為什麼要用中文分詞呢?
在sphinx的測試程式中,我們可以看到他如果將我們輸入的關鍵字做處理後丟到index去搜尋,例如:

我要搜尋 "皇帝內經"
當沒有使用中文分詞功能時,sphinx會將皇帝內經分成 4 個獨立的字,丟到 index 搜尋,再依照最後的 weight 回傳,所以在某些狀況下,精準度就比較不符合我們的思維。

在使用中文分詞之後,只要在分詞檔中,我們建立
"皇帝 1500"
"內經 1500"

sphinx 便會將皇帝內經分成"皇帝"和"內經"去搜尋,這樣是不是準多了??

再或者我們建立
"皇帝 1500"
"皇帝內經 1501"

sphinx 便會將皇帝內經4個字一起去搜尋,達到 100% match的搜尋。

當然這些中文分詞的內容是要靠經驗以及公司的domain去建立,要從無到有的話,大家就辛苦點吧。

2010年3月18日 星期四

Sphinx 索引建立自己會中斷

最近公司要尋求 search engine 的解決方案,同事找了一套 Sphinx 的軟體(open source SQl full-text search engine)

安裝於 FreeBSD 8.0 的系統下,安裝的過程還算順利,按照官方 Document 的步驟都沒問題。

但是在設定好 config 檔後,開始建立索引卻一直有問題,因為我們的資料總共 300 萬左右,每次建到 46 萬的時候,就會自動結束,找了很久都找不太到原因。最後想到我們 table 的 schema ,在 primary 並未使用正整數的欄位,而是使用 char 的欄位。

於是我們便將所有的資料 Copy 到另一個相同但多加了一個正整數的 primary 欄位,開始建立索引就可以完全的建完。雖然只有幾個欄位,不過 300 萬的資料,居然不到 1 分鐘就建好索引了...飛快的速度。

不過在中文字方面似乎仍有問題,後續繼續研究。