Sphinx 简介
Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL,PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx 特别为一些脚本语言设计搜索 API 接口,如 PHP,Python,Perl,Ruby 等,同时为 MySQL 也设计了一个存储引擎插件。
Sphinx 是独立的搜索服务端,不依赖 MySQL,当 Sphinx 和 MySQL 结合部署时,Sphinx 的数据来源为 MySQL。服务器安装 Sphinx,由 sphinx.conf 配置文件指定 Sphinx 的数据源,如何读取 MySQL 的数据内容,设置 Sphinx 对 MySQL 数据库的哪个表哪些字段建立索引,索引的返回数据必须是数值型。
Sphinx 单一索引最大可包含 1 亿条记录,在 1 千万条记录情况下的查询速度为 0.x 秒(毫秒级)。Sphinx 创建索引的速度为:创建 100 万条记录的索引只需 3~4 分钟,创建 1000 万条记录的索引可以在 50 分钟内完成,而只包含最新 10 万条记录的增量索引,重建一次只需几十秒。
正确使用 Sphinx 搜索数据的操作方式主要有三种:
1、命令行的 search 工具:/usr/local/webserver/sphinx/bin/search –i threads test
2、php 的 api 接口查询:原理是直接用 fsockopen 连接端口,传递数据取得返回结果。 Sphinx 官方已经提供 php 的 api 接口,可以 include api 查询(本方案以该查询方法为主),也可以将其源代码编译成 php 扩展而无需 include。
3、在 mysql 中将 Sphinx 安装为 SphinxSE 存储引擎,通过 SphinxSE 方式调用 Sphinx。
因 Sphinx 搜索结果只返回 INT 类型数据,部署 Sphinx 搜索的核心是由搜索入口(search.php)提交的关键词到 Sphinx 中搜索,Sphinx 返回对应的 tid、pid 等信息,再依据 tid、pid 到 cdb_threads 或者 cdb_posts 中搜索,得到结果集展示在页面上。
Sphinx 的搜索速度非常快,而 tid/pid 都是主键查询,总体来说虽然用了多次查询,但是速度仍然非常快。
Sphinx 全文检索方案架构图
Sphinx 工作流程图
1. Database
数据源,是 Sphinx 做索引的数据来源。因为 Sphinx 是无关存储引擎、数据库的,所以数据源可以是 MySQL、PostgreSQL、XML 等数据。
2. Indexer
索引程序,从数据源中获取数据,并将数据生成全文索引。可以根据需求,定期运行 Indexer 达到定时更新索引的需求。
3. Searchd
Searchd 直接与客户端程序进行对话,并使用 Indexer 程序构建好的索引来快速地处理搜索查询。
4. APP
客户端程序。接收来自用户输入的搜索字符串,发送查询给 Searchd 程序并显示返回结果。
Sphinx 工作原理
Sphinx 的整个工作流程就是 Indexer 程序到数据库里面提取数据,对数据进行分词,然后根据生成的分词生成单个或多个索引,并将它们传递给 searchd 程序。然后客户端可以通过 API 调用进行搜索。
Sphinx 中文分词
中文的全文检索和英文等 latin 系列不一样,后者是根据空格等特殊字符来断词,而中文是根据语义来分词,起搜索中应以词为依据,独立存在的单个汉字搜索几乎没有意义。目前大多数数据库尚未支持中文全文检索,如 Mysql。故,国内出现了一些 Mysql 的中文全文检索的插件,做的比较好的有 hightman 的中文分词。Sphinx 如果需要对中文进行全文检索,也得需要一些插件来补充。其中我知道的插件有 coreseek 和 sfc 。
1. Coreseek
Coreseek 是现在用的最多的 sphinx 中文全文检索,它提供了为 Sphinx 设计的中文分词包 LibMMSeg 。并提供了多个系统的二进制发行版,其中有 rpm,deb 及 windows 下的二进制包。另外,coreseek 也为 sphinx 贡献了以下事项:
-
GBK 编码的数据源支持
-
采用 Chih-Hao Tsai MMSEG 算法的中文分词器
2. sfc
sfc(sphinx-for-chinese)是由网友 happy 兄提供的另外一个中文分词插件。其中文词典采用的是 xdict。据其介绍,经过测试,目前版本在索引速度上(Linux 测试平台)基本上能够达到索引 UTF-8 英文的一半,即官方宣称速度的一半。(时间主要是消耗在分词上)。 现提供了与 sphinx 最新版(sphinx 0.9.10)同步的 sphinx-for-chinese-0.9.10-dev-r2006.tar.gz 。此版本增加了 sql_attr_string,经过本人的测试。其安装和配置都非常方便。happy 兄在分词方面还有另外一个贡献——php-mmseg,这是 php 对中文分词的一个扩展库。
Sphinx 安装步骤
1.下载源码
1.下载地址
https://github.com/zwxhenu/coreseek
2. 下载命令
git clone https://github.com/zwxhenu/coreseek
2.安装 mmseg3 中文分词
** 1. 安装依赖**
yum -y install gcc gcc-c++ autoconf python python-devel libiconv libtool
** 2. 编译安装 mmseg-3.2.14**
cd mmseg-3.2.14
./configure --prefix=/usr/local/mmseg3
make
make install
** 3. 遇到的问题**
1). 遇到 error:cannot find input file: src/Makefile.in
yum -y install libtool
aclocal
libtoolize --force
automake --add-missing
autoconf
autoheader
make clean
./configure --prefix=/usr/local/mmseg3
make
make install
2). 没有规则可以创建“all-am”需要的目标“data/uni.lib
删除Makefile.am中的data/uni.lib
automake
./configure --prefix=/usr/local/mmseg3
make
make install
3). 生产 uni.lib
cd /usr/local/mmseg3/etc/
/usr/local/mmseg3/bin/mmseg -u unigram.txt
cp unigram.txt.uni uni.lib
3.安装 coreseek
** 1.安装依赖软件 **
yum -y install expat expat-devel
2. 检查环境
sh buildconf.sh
** 3. 检查环境出问题**
- 在 csft-4.1/buildconf.sh 文件&& aclocal \ 后加入:
&& automake --add-missing \
2) 把 csft-4.1/configure.ac 文件中的 AM_INIT_AUTOMAKE([-Wall -Werror foreign])改为:
AM_INIT_AUTOMAKE([-Wall foreign])
- 在 csft-4.1/configure.ac 文件中的 AC_PROG_RANLIB 后面加上:
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
- 在 csft-4.1/src/sphinxexpr.cpp 文件中, 替换所有:
T val = ExprEval ( this->m_pArg, tMatch ); 为T val = this->ExprEval ( this->m_pArg, tMatch );
** 4. 配置编译选项 **
./configure --prefix=/usr/local/coreseek --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql
** 5. 配置编译选项问题解决**
1). 遇到 MySQL include files... configure: error: missing include files.解决办法:
yum install mysql-community-embedded-devel.x86_64 mysql-community-devel.x86_64 mysql++-devel.x86_64
2). 提示 libiconv 无法找到,需要修改 vi src/Makefile 文件,找 LIBS = 开头的行:
将LIBS = -lm -lz -lexpat -L/usr/local/lib –lpthread修改成:
LIBS = -lm -lz -lexpat -liconv -L/usr/local/lib -lpthread
** 5. 编译&安装**
make;
make install
4.命令行测试 mmseg 分词,coresekk 搜索
** 1. 进入测试目录 **
cd testpack
** 2. 检查终端是否能显示中文 **
cat var/test/test.xml #此时应该正确显示中文
** 3. 进行分词和创建索引 **
/usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml
/usr/local/coreseek/bin/indexer -c etc/csft.conf --all
** 4. 检查搜索结果 **
- 命令:
/usr/local/coreseek/bin/search -c etc/csft.conf 网络搜索
- 结果:
Coreseek Fulltext 3.2 [ Sphinx 0.9.9-release (r2117)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/csft.conf'...
index 'xml': query '网络搜索 ': returned 1 matches of 1 total in 0.003 sec
displaying matches:
1. document=1, weight=1, published=Thu Apr 1 22:20:07 2010, author_id=1
words:
1. '网络': 1 documents, 1 hits
2. '搜索': 2 documents, 5 hits
5.配置 sphinx 与 mysql
** 1. threads 源定义**
source threads
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = mysql57@fangstar
sql_db = discuz
sql_port = 3306 # optional, default is 3306
sql_sock = /var/lib/mysql/mysql.sock
sql_query_pre = SET NAMES utf8
#sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre = CREATE TABLE IF NOT EXISTS pre_common_sphinxcounter ( indexid INTEGER PRIMARY KEY NOT NULL,maxid INTEGER NOT NULL)
sql_query_pre = REPLACE INTO pre_common_sphinxcounter SELECT 1, MAX(tid)-10 FROM pre_forum_thread
sql_query = SELECT t.tid AS id,t.tid,t.subject,t.digest,t.displayorder,t.authorid,t.lastpost,t.special \
FROM pre_forum_thread AS t \
WHERE t.tid>=$start AND t.tid<=$end
sql_query_range = SELECT (SELECT MIN(tid) FROM pre_forum_thread),maxid FROM pre_common_sphinxcounter WHERE indexid=1
sql_range_step = 4096
sql_attr_uint = tid
sql_attr_uint = digest
sql_attr_uint = displayorder
sql_attr_uint = authorid
sql_attr_uint = special
sql_attr_timestamp = lastpost
sql_query_info = SELECT * FROM pre_forum_thread WHERE tid=$id
}
** 2. threads index 定义**
index threads
{
source = threads
path = /usr/local/coreseek/var/data/threads
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
charset_type = zh_cn.utf-8
charset_dictpath = /usr/local/mmseg3/etc/
min_prefix_len = 0
min_infix_len = 1
ngram_len = 0
html_strip = 0
}
** 3. threads_minute 源定义**
source threads_minute: threads
{
sql_query_pre =
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_range = SELECT maxid+1,(SELECT MAX(tid) FROM pre_forum_thread) FROM pre_common_sphinxcounter WHERE indexid=1
}
** 4. threads_minute 索引定义 **
#threads_minute
index threads_minute : threads
{
source = threads_minute
path = /usr/local/coreseek/var/data/threads_minute #windows下最好用全路径
}
** 5. posts 源定义**
#posts
source posts
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = mysql57@fangstar
sql_db = discuz
sql_port = 3306
sql_query_pre = SET NAMES utf8
# sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_pre = REPLACE INTO pre_common_sphinxcounter SELECT 2, MAX(pid)-2 FROM pre_forum_post
sql_query = SELECT p.pid AS id,p.tid,p.subject,p.message,t.digest,t.displayorder,t.authorid,t.lastpost,t.special \
FROM pre_forum_post AS p LEFT JOIN pre_forum_thread AS t USING(tid) \
WHERE p.pid>=$start AND p.pid<=$end
sql_query_range = SELECT (SELECT MIN(pid) FROM pre_forum_post),maxid FROM pre_common_sphinxcounter WHERE indexid=2
sql_range_step = 4096
sql_attr_uint = tid
sql_attr_uint = digest
sql_attr_uint = displayorder
sql_attr_uint = authorid
sql_attr_uint = special
sql_attr_timestamp =lastpost
sql_query_info = SELECT * FROM pre_forum_post WHERE pid=$id
}
6. posts index 定义
#posts
index posts
{
source = posts
path = /usr/local/coreseek/var/data/posts #windows下最好用全路径
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
charset_dictpath = /usr/local/mmseg3/etc/ #BSD、Linux环境下设置,/符号结尾
charset_type = zh_cn.utf-8
#charset_debug = 0
ngram_len = 0
}
** 7. posts_minute 源定义**
#posts_minute
source posts_minute : posts
{
sql_query_pre =
sql_query_pre = SET NAMES utf8
# sql_query_pre = SET SESSION query_cache_type=OFF
sql_query_range = SELECT maxid+1,(SELECT MAX(pid) FROM pre_forum_post) FROM pre_common_sphinxcounter WHERE indexid=2
}
8. posts_minute index 定义
#posts_minute
index posts_minute : posts
{
source = posts_minute
path = /usr/local/coreseek/var/data/posts_minute #windows下最好用全路径
}
9. 全局 indexer 定义
indexer
{
mem_limit = 256M
}
10. searchd 服务定义
searchd
{
listen = 9312
listen = /tmp/sphinx.sock
log = /var/log/spinhx/searchd.log
query_log = /var/log/spinhx/query.log
read_timeout = 5
client_timeout = 300
max_children = 30
pid_file = /var/run/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 0
unlink_old = 1
mva_updates_pool = 1M
max_packet_size = 8M
max_filters = 256
max_filter_values = 4096
}
## 6. 启动服务,创建索引
1. 创建索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf -all
2.启动后台服务 searchd
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf
3. 后台服务测试
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf aaa
4. 自动化命令
crontab -e
* */4 * * * /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf -all --rotate
5. 关闭后台服务 searchd
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf --stop
#discuz 后台配置
1. 按照下图进行搜索设置
2. 点击提交
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于