在Linux下安装Sphinx+MySQL5.1x+SphinxSE+mmseg中文分词
2013-06-08 21:28
477 查看
一、原生MySQL存储引擎检索流程:
二、基于Sphinx存储引擎检索:
三、安装前准备文件:
四、开始安装:
1)通过yum命令更新依赖包(与php环境搭建依赖包一起更新了)
2)安装MySQL+SphinxSE,(进入软件包所在的目录)
安装完成启动MySQL后查看sphinx存储引擎是否安装成功
在mysql命令行下执行
3)安装Sphinx全文检索服务器
说明:
Sphinx默认不支持中文索引及检索, 以前用Coreseek的补丁来解决,目前Coreseek不单独提供补丁文件,而基于sphinx开发了Coreseek全文检索服务器,Coreseek应该是现在用的最多的sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg包含mmseg中文分词,其实coreseek-3.2.14.tar.gz中已经包含了sphinx,前面安装SphinxSE时也可以使用这个压缩包里的mysqlse。
[align=left]则进入当前目录下的src目录,编辑Makefile文件 将[/align]
[align=left]LIBS = -lm -lz -lexpat -L/usr/local/lib -lrt -lpthread[/align]
[align=left]修改为LIBS = -lm -lz -lexpat -liconv -L/usr/local/lib -lrt -lpthread[/align]
[align=left]然后重新编即可。[/align]
[align=left]
[/align]
[align=left]
[/align]
代码段source src1{***} 代表数据源里面主要包含了数据库的配置信息,src1表示数据源名字,可以随便写。
代码段index test1{***} 代表为哪个数据源创建索引,与source *** 是成对出现的,其中的source参数的值必须是某一个数据源的名字。
其他参数可以查看手册,这里不再赘述。
生成索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf --all
其中参数--all表示生成所有索引
当然也可以是索引的名字例如:/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conftest1
执行后可以在/usr/local/coreseek/var/data目录中看到多出一些文件,是以索引名为文件名的不同的扩展名的文件
在不启动sphinx的情况下即可测试命令:
[align=left]
[/align]
[align=left]五、测试[/align]
[align=left]
[/align]
[align=left]1)测试MySQL+sphinx[/align]
可以看到将内容中含有number数据的数据查询出来。
过滤查询
同样也可以测试中文(需将命令行终端编码调整为utf-8),如下:
可以看到我们输入的查询文字已经被拆分成了两个词,只是因为我们的测试数据中没有中文数据查询结果为空。我们插入几条新数据。
注:插入新数据后需要重新生成索引
我们搜索的词语是“研究生创业”,可以看到词语被拆分成了研究生和创业两个词,虽然有两条记录都包含“创业和”研究生”这几个字但是“研究生命科学”中的“研究生”三个字虽然是紧挨着的但是不是一个词语,结果是只匹配一条“研究生自主创业”,我们再搜索“研究”这个词语。
同样匹配一条记录,而“研究生的故事”和“研究生自主创业”的词语却没有被查询出来,可以看出sphinx与分词技术结合可以匹配出相关度更高的结果。
当然我们的目的不仅限与命令行下的测试,我们可以通过搜索API调用来执行搜索,搜索API支持PHP、Python、Perl、Rudy和Java。如果从PHP脚本检索需要先启动守护进程searchd,PHP脚本需要连接到searchd上进行检索:
在解压后的sphinx-0.9.9/api目录下的sphinxapi.php就是sphinx官方为我们提供的API文件(其实也可以使用PHP的sphinx扩展),只需将其包含进自己的PHP脚本文件就可以了。
示例代码:
Array
(
[error] =>
[warning] =>
[status] => 0
[fields] => Array
(
[0] => title
[1] => content
)
[attrs] => Array
(
[group_id] => 1
[date_added] => 2
)
[matches] => Array
(
[5] => Array
(
[weight] => 2
[attrs] => Array
(
[group_id] => 2
[date_added] => 1296491832
)
)
)
[total] => 1
[total_found] => 1
[time] => 0.078
[words] => Array
(
[研究生] => Array
(
[docs] => 1
[hits] => 2
)
[创业] => Array
(
[docs
ab4b
] => 2
[hits] => 2
)
)
)
在matches中的就是查询结果,我们注意到sphinx是将记录中的主键ID值返回而不是返回所有数据,上面的例子中的键名5就是记录的ID(如果在查询前执行$cl->SetArrayResult (
true );则数组结构会有些许差异)。至此搜索服务器已经为我们完成了大部分工作,接下来我们通过主键ID值来查询我们想要的数据就可以了。
2) 测试MySQL+Sphinx EX
说明:
SphinxSE是一个可以编译进MySQL 5.x版本的MySQL存储引擎,它利用了该版本MySQL的插件式体系结构。尽管被称作“存储引擎”,SphinxSE自身其实并不存储任何数据。它其实是一个允许MySQL服务器与searchd交互并获取搜索结果的嵌入式客户端。所有的索引和搜索都发生在MySQL之外。
要通过SphinxSE搜索,需要建立特殊的ENGINE=SPHINX的“搜索表”,然后使用SELECT语句从中检索,把全文查询放在WHERE子句中。
首先创建一张表t1
搜索表前三列的类型必须是INTEGER,INTEGER和VARCHAR,这三列分别对应文档ID,匹配权值和搜索查询。查询列必须被索引,其他列必须无索引。列的名字会被忽略,所以可以任意命名,参数CONNECTION来指定用这个表搜索时的默认搜索主机、端口号和索引,语法格式:CONNECTION="sphinx://HOST:ORT/INDEXNAME"。
显示如下结果:
+----+--------------------+-----------------------+
| id | title | content |
+----+--------------------+-----------------------+
| 5 | 研究生的故事 | 研究生自主创业 |
+----+--------------------+-----------------------+
1 row in set (0.04 sec)
结果返回了我们想要的数据,可见利用SphinxSE可以仅仅在SQL语句上做很小的改动即可很方便的实现全文检索!
在php程序中测试也一样,如下代码:
安装与简单测试到此为止!
二、基于Sphinx存储引擎检索:
三、安装前准备文件:
四、开始安装:
1)通过yum命令更新依赖包(与php环境搭建依赖包一起更新了)
yum -y install gcc g++ gcc-c++ libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers patch libtool automake imake mysql-devel expat-devel
2)安装MySQL+SphinxSE,(进入软件包所在的目录)
tar zxvf mysql-5.1.55.tar.gz tar zxvf sphinx-0.9.9.tar.gz cp -r sphinx-0.9.9/mysqlse/ mysql-5.1.55/storage/sphinx cd mysql-5.1.55 ./BUILD/autorun.sh ./configure --prefix=/usr/local/webserver/mysql/ --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-big-tables --with-readline --with-ssl --with-embedded-server --enable-local-infile --with-plugins=partition,innobase,myisammrg,sphinx make make install
/usr/sbin/groupadd mysql /usr/sbin/useradd -g mysql mysql chmod +w /usr/local/webserver/mysql chown -R mysql:mysql /usr/local/webserver/mysql cd ../ 创建目录 mkdir -p /data0/mysql/3306/data/ mkdir -p /data0/mysql/3306/binlog/ mkdir -p /data0/mysql/3306/relaylog/ chown -R mysql:mysql /data0/mysql/ 以mysql用户帐号的身份建立数据表: /usr/local/webserver/mysql/bin/mysql_install_db --basedir=/usr/local/webserver/mysql --datadir=/data0/mysql/3306/data --user=mysql vi /data0/mysql/3306/my.cnf 输入 [client] character-set-server = utf8 port = 3306 socket = /tmp/mysql.sock [mysqld] character-set-server = utf8 replicate-ignore-db = mysql replicate-ignore-db = test replicate-ignore-db = information_schema user = mysql port = 3306 socket = /tmp/mysql.sock basedir = /usr/local/webserver/mysql datadir = /data0/mysql/3306/data log-error = /data0/mysql/3306/mysql_error.log pid-file = /data0/mysql/3306/mysql.pid open_files_limit = 10240 back_log = 600 max_connections = 5000 max_connect_errors = 6000 table_cache = 614 external-locking = FALSE max_allowed_packet = 4M sort_buffer_size = 1M join_buffer_size = 1M thread_cache_size = 300 #thread_concurrency = 8 query_cache_size = 4M query_cache_limit = 1M query_cache_min_res_unit = 2k default-storage-engine = MyISAM thread_stack = 192K transaction_isolation = READ-COMMITTED tmp_table_size = 4M max_heap_table_size = 16M long_query_time = 3 log-slave-updates log-bin = /data0/mysql/3306/binlog/binlog binlog_cache_size = 1M binlog_format = MIXED max_binlog_cache_size = 2M max_binlog_size = 1G relay-log-index = /data0/mysql/3306/relaylog/relaylog relay-log-info-file = /data0/mysql/3306/relaylog/relaylog relay-log = /data0/mysql/3306/relaylog/relaylog expire_logs_days = 30 key_buffer_size = 8M read_buffer_size = 1M read_rnd_buffer_size = 2M bulk_insert_buffer_size = 4M myisam_sort_buffer_size = 16M myisam_max_sort_file_size = 1G myisam_repair_threads = 1 myisam_recover interactive_timeout = 120 wait_timeout = 120 skip-name-resolve #master-connect-retry = 10 slave-skip-errors = 1032,1062,126,1114,1146,1048,1396 #master-host = 192.168.1.2 #master-user = username #master-password = password #master-port = 3306 server-id = 1 innodb_additional_mem_pool_size = 8M innodb_buffer_pool_size = 64M innodb_data_file_path = ibdata1:256M:autoextend innodb_file_io_threads = 4 innodb_thread_concurrency = 8 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 4M innodb_log_file_size = 32M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_file_per_table = 0 #log-slow-queries = /data0/mysql/3306/slow.log #long_query_time = 10 [mysqldump] quick max_allowed_packet = 8M =========================================================================== 创建shell管理脚本 vi /data0/mysql/3306/mysql 输入 #!/bin/sh mysql_port=3306 mysql_username="root" mysql_password="12345678" function_start_mysql() { printf "Starting MySQL...\n" /bin/sh /usr/local/webserver/mysql/bin/mysqld_safe --defaults-file=/data0/mysql/${mysql_port}/my.cnf 2>&1 > /dev/null & } function_stop_mysql() { printf "Stoping MySQL...\n" /usr/local/webserver/mysql/bin/mysqladmin -u ${mysql_username} -p${mysql_password} -S /tmp/mysql.sock shutdown } function_restart_mysql() { printf "Restarting MySQL...\n" function_stop_mysql sleep 5 function_start_mysql } function_kill_mysql() { kill -9 $(ps -ef | grep 'bin/mysqld_safe' | grep ${mysql_port} | awk '{printf $2}') kill -9 $(ps -ef | grep 'libexec/mysqld' | grep ${mysql_port} | awk '{printf $2}') } if [ "$1" = "start" ]; then function_start_mysql elif [ "$1" = "stop" ]; then function_stop_mysql elif [ "$1" = "restart" ]; then function_restart_mysql elif [ "$1" = "kill" ]; then function_kill_mysql else printf "Usage: /data0/mysql/${mysql_port}/mysql {start|stop|restart|kill}\n" fi ====================================================================================== chmod +x /data0/mysql/3306/mysql 启动mysql /data0/mysql/3306/mysql start 登陆mysql /usr/local/webserver/mysql/bin/mysql -u root -p -S /tmp/mysql.sock 创建用户并赋予权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '12345678'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY '12345678'; ======================================================================================
安装完成启动MySQL后查看sphinx存储引擎是否安装成功
在mysql命令行下执行
show engines;如果出现如下图红色方框内的信息说明SphinxSE已经安装成功!
3)安装Sphinx全文检索服务器
说明:
Sphinx默认不支持中文索引及检索, 以前用Coreseek的补丁来解决,目前Coreseek不单独提供补丁文件,而基于sphinx开发了Coreseek全文检索服务器,Coreseek应该是现在用的最多的sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg包含mmseg中文分词,其实coreseek-3.2.14.tar.gz中已经包含了sphinx,前面安装SphinxSE时也可以使用这个压缩包里的mysqlse。
安装autoconf tar zxvf autoconf-2.64.tar.gz cd autoconf-2.64 ./configure --prefix=/usr make make install cd .. 安装Coreseek tar zxvf coreseek-3.2.14.tar.gz cd coreseek-3.2.14 cd mmseg-3.2.14/ ./bootstrap ./configure --prefix=/usr/local/mmseg3 make make install cd ../csft-3.2.14/ sh buildconf.sh ./configure --prefix=/usr/local/coreseek --without-python --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql --host=arm make make install注:若上面执行完make后报如下错误:
[align=left]则进入当前目录下的src目录,编辑Makefile文件 将[/align]
[align=left]LIBS = -lm -lz -lexpat -L/usr/local/lib -lrt -lpthread[/align]
[align=left]修改为LIBS = -lm -lz -lexpat -liconv -L/usr/local/lib -lrt -lpthread[/align]
[align=left]然后重新编即可。[/align]
[align=left]
[/align]
[align=left]
[/align]
cd /usr/local/coreseek/etc 进入配置目录通过命令ls可以看到3个文件 example.sql sphinx.conf.dist sphinx-min.conf.dist 其中example.sql是示例sql脚本我们将其导入到数据库中的test数据库中作为测试数据(会创建两张表 documents和tags) vi sphinx.conf 输入以下内容 source src1 { type = mysql sql_host = localhost sql_user = root sql_pass =12345678 sql_db = test sql_port = 3306 # optional, default is 3306 sql_sock = /tmp/mysql.sock sql_query_pre = SET NAMES utf8 sql_query = \ SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \ FROM documents sql_attr_uint = group_id sql_attr_timestamp = date_added sql_query_info = SELECT * FROM documents WHERE id=$id } index test1 { source = src1 path = /usr/local/coreseek/var/data/test1 docinfo = extern charset_type = zh_cn.utf-8 mlock = 0 morphology = none min_word_len = 1 html_strip = 0 charset_dictpath = /usr/local/mmseg3/etc/ ngram_len = 0 } indexer { mem_limit = 32M } 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/coreseek/var/log/searchd.pid max_matches = 1000 seamless_rotate = 1 preopen_indexes = 0 unlink_old = 1 }说明:
代码段source src1{***} 代表数据源里面主要包含了数据库的配置信息,src1表示数据源名字,可以随便写。
代码段index test1{***} 代表为哪个数据源创建索引,与source *** 是成对出现的,其中的source参数的值必须是某一个数据源的名字。
其他参数可以查看手册,这里不再赘述。
生成索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf --all
其中参数--all表示生成所有索引
当然也可以是索引的名字例如:/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conftest1
执行后可以在/usr/local/coreseek/var/data目录中看到多出一些文件,是以索引名为文件名的不同的扩展名的文件
在不启动sphinx的情况下即可测试命令:
[align=left]
[/align]
[align=left]五、测试[/align]
[align=left]
[/align]
[align=left]1)测试MySQL+sphinx[/align]
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf number
可以看到将内容中含有number数据的数据查询出来。
过滤查询
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf number --filter group_id 2限定group_id 为2 返回一条记录
同样也可以测试中文(需将命令行终端编码调整为utf-8),如下:
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf 研究生创业
可以看到我们输入的查询文字已经被拆分成了两个词,只是因为我们的测试数据中没有中文数据查询结果为空。我们插入几条新数据。
INSERT INTO `test`.`documents` ( `id` , `group_id` , `group_id2` , `date_added` , `title` , `content` ) VALUES ( NULL , '2', '3', '2011-02-01 00:37:12', '研究生的故事', '研究生自主创业' ), ( NULL , '1', '1', '2011-01-28 00:38:22', '研究', '为了创业而研究生命科学' );我们再来看以下数据库中的主要数据,如下:
注:插入新数据后需要重新生成索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf test1然后执行查询测试:
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf 研究生创业
我们搜索的词语是“研究生创业”,可以看到词语被拆分成了研究生和创业两个词,虽然有两条记录都包含“创业和”研究生”这几个字但是“研究生命科学”中的“研究生”三个字虽然是紧挨着的但是不是一个词语,结果是只匹配一条“研究生自主创业”,我们再搜索“研究”这个词语。
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf 研究
同样匹配一条记录,而“研究生的故事”和“研究生自主创业”的词语却没有被查询出来,可以看出sphinx与分词技术结合可以匹配出相关度更高的结果。
当然我们的目的不仅限与命令行下的测试,我们可以通过搜索API调用来执行搜索,搜索API支持PHP、Python、Perl、Rudy和Java。如果从PHP脚本检索需要先启动守护进程searchd,PHP脚本需要连接到searchd上进行检索:
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf
在解压后的sphinx-0.9.9/api目录下的sphinxapi.php就是sphinx官方为我们提供的API文件(其实也可以使用PHP的sphinx扩展),只需将其包含进自己的PHP脚本文件就可以了。
示例代码:
<?php include('sphinxapi.php'); $cl = new SphinxClient(); //设置sphinx服务器地址与端口,如果是本机则可以为localhost $cl->SetServer( "192.168.16.6", 9312 ); //以下设置用于返回数组形式的结果 $cl->SetArrayResult ( true ); //$cl->SetMatchMode( SPH_MATCH_ANY );//匹配模式 //$cl->SetFilter( 'group_id', array( 2 ) ); $result = $cl->Query( '研究生创业', 'test1' ); //参数 关键字 索引名 if ( $result === false ) { echo "Query failed: " . $cl->GetLastError() . ".\n"; } else { if ( $cl->GetLastWarning() ) { echo "WARNING: " . $cl->GetLastWarning() . ""; } echo '<pre>'; print_r( $result ); } ?>执行后的结果为:
Array
(
[error] =>
[warning] =>
[status] => 0
[fields] => Array
(
[0] => title
[1] => content
)
[attrs] => Array
(
[group_id] => 1
[date_added] => 2
)
[matches] => Array
(
[5] => Array
(
[weight] => 2
[attrs] => Array
(
[group_id] => 2
[date_added] => 1296491832
)
)
)
[total] => 1
[total_found] => 1
[time] => 0.078
[words] => Array
(
[研究生] => Array
(
[docs] => 1
[hits] => 2
)
[创业] => Array
(
[docs
ab4b
] => 2
[hits] => 2
)
)
)
在matches中的就是查询结果,我们注意到sphinx是将记录中的主键ID值返回而不是返回所有数据,上面的例子中的键名5就是记录的ID(如果在查询前执行$cl->SetArrayResult (
true );则数组结构会有些许差异)。至此搜索服务器已经为我们完成了大部分工作,接下来我们通过主键ID值来查询我们想要的数据就可以了。
2) 测试MySQL+Sphinx EX
说明:
SphinxSE是一个可以编译进MySQL 5.x版本的MySQL存储引擎,它利用了该版本MySQL的插件式体系结构。尽管被称作“存储引擎”,SphinxSE自身其实并不存储任何数据。它其实是一个允许MySQL服务器与searchd交互并获取搜索结果的嵌入式客户端。所有的索引和搜索都发生在MySQL之外。
要通过SphinxSE搜索,需要建立特殊的ENGINE=SPHINX的“搜索表”,然后使用SELECT语句从中检索,把全文查询放在WHERE子句中。
首先创建一张表t1
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/test1";
搜索表前三列的类型必须是INTEGER,INTEGER和VARCHAR,这三列分别对应文档ID,匹配权值和搜索查询。查询列必须被索引,其他列必须无索引。列的名字会被忽略,所以可以任意命名,参数CONNECTION来指定用这个表搜索时的默认搜索主机、端口号和索引,语法格式:CONNECTION="sphinx://HOST:ORT/INDEXNAME"。
执行SQL语句 select d.id,d.title,d.content from t1 join documents as d on t1.id = d.id and t1.query = '研究生创业';
显示如下结果:
+----+--------------------+-----------------------+
| id | title | content |
+----+--------------------+-----------------------+
| 5 | 研究生的故事 | 研究生自主创业 |
+----+--------------------+-----------------------+
1 row in set (0.04 sec)
结果返回了我们想要的数据,可见利用SphinxSE可以仅仅在SQL语句上做很小的改动即可很方便的实现全文检索!
在php程序中测试也一样,如下代码:
<?php mysql_connect('192.168.1.75', 'user', '12345678'); mysql_select_db('test'); mysql_query('set names uft8'); if($_POST["searchwords"]){ $search = $_POST["searchwords"]; $result = mysql_query("select a.id,a.title,a.content,a.author from t2 join article as a on t2.id = a.id and t2.query = '$search'"); while($rows = mysql_fetch_assoc($result)){ $arr[] = $rows; } echo "<table border=1>"; echo "<th>id</th><th>title</th><th>content</th>"; foreach($arr as $val){ echo '<tr>'.'<td>'.$val['id'].'</td>'.'<td>'.$val['title'].'</td>'.'<td>'.$val['content'].'</td>'.'</tr>'; } echo "</table>"; } ?>
安装与简单测试到此为止!
相关文章推荐
- Linux-CentOS Elasticsearch 安装ik中文分词
- 中文分词插件SCWS-1.2.3 在Linux环境的安装说明(包括php扩展)
- 在linux 下安装 solr 的IK中文分词
- Linux下带有中文分词的sphinx—coreseek安装和配置--2
- solr4.7安装配置,solrcloud安装配置,中文分词使用步骤
- 在linux中安装中文包
- linux学习之--硬盘安装ubuntu方法(转自ubuntu中文论坛fff969)
- Linux下安装中文输入法
- sphinx的coreseek4.0中文分词的安装
- VMware虚拟机安装Linux英文改中文系统并更新yum安装输入法
- Linux系统下安装中文输入法 fcitx
- Linux系统安装中文环境,中文帮助,中文输入法的实现
- Elasticsearch安装中文分词插件ik
- Linux - Ubuntu中文输入法安装(Ubuntu 12.04)
- 用DVD安装上linux,不支持中文,修改/etc/sysconfig/i18n,也不行
- wamp下安装scws(中文分词)
- linux下安装中文输入法
- 开源php中文分词系统SCWS安装和使用实例_php实例