ITPUX技术网

交流 . 资讯 . 分享
Make progress together!
Linux操作系统下Oracle11g R2 RAC 安装配置教程
Oracle数据库培训-备份恢复-性能优化-集群容灾
Oracle数据库DBA高级工程师培训视频

LAMP+Coreseek中文检索引擎使用详解

内容发布:luashin| 发布时间:2017-6-8 21:07:20
LAMP+Coreseek中文检索引擎使用详解

一、安装PHP的sphinx扩展:
=====================1、安装libsphinxclient================
cd coreseek-3.2.14/csft-3.2.14/api/libsphinxclient/

安装sphinxclient
# vim coreseek-3.2.14/testpack/api/libsphinxclient/sphinxclient.c
将280行void sock_close ( int sock );
改为static void sock_close ( int sock );
sed -ie '280s/^/static /' sphinxclient.c
注意:这是一个bug必须修改
#./configure --prefix=/usr/local/sphinxclient && make && make install
# ./configure && make -j 4 && make install

====================2、安装sphinx的PHP扩展===================
wget http://pecl.php.net/get/sphinx-1.3.3.tgz
tar -zxvf sphinx-1.3.3.tgz && rm -rf sphinx-1.3.3.tgz
cd sphinx-1.3.3

使用安装php时生成的phpize来生成configure配置文件
/usr/local/php/bin/phpize

/usr/bin/phpize
# 具体用哪个要取决于你的phpize文件所在的目录,这时你应该用 whereis phpize 来查看路径

./configure --with-php-config=/usr/bin/php-config && make -j 4 && make install
# 其中php-config和phpize所在的目录是相同的,比如上面我用 /usr/bin/phpize,则在这一步用 ./configure --with-php-config=/usr/bin/php-config。而/usr/local/sphinxclient就是上面的libsphinxclient的安装目录
make && make install

#注意,如果你的php版本是5.4,那么在这一步中会出现错误,提示在 sphinx.c:105:2,可以按下面方式修改:
# vim sphinx.c找到105行
将retval = std_hnd->read_property(object, member, type TSRMLS_CC);
修改成
retval = std_hnd->read_property(object, member, type TSRMLS_CC, NULL);

#重新编译安装
# ./configure --with-php-config=/usr/bin/php-config --with-sphinx=/usr/local/sphinxclient && make && make install

安装完之后我们还要修改PHP.ini文件:
vim /etc/php.ini    #具体php.ini的位置自己查哈
#在php.ini文件的最后一行添加:
#extension="sphinx.so"
extension=/usr/lib64/php/modules/sphinx.so

重启apache服务器
systemctl restart httpd.service

重启后,php文件内添加echo phpinfo();,在详情页面中假如有:
cat > /var/www/html/index.php <<EOF
<?php
phpinfo();
?>
EOF

测试php页面是不否包含有sphinx

则说明安装sphinx的PHP扩展成功!

二、sphinx配置文件和测试表
建立sphinx.conf配置文件
cd /usr/local/coreseek/etc
cp -v sphinx.conf.dist sphinx.conf     #sphinx配置文件的默认名就是sphinx.conf

sphinx.conf配置文件结构介绍
#主数据源
source main{
{
#增量数据源
source delta:main{
}
#主数据索引
index main{
}
#增量数据索引
index delta:main{
}
#分布式索引
index dist1{
}
#索引器
indexer{
}
#服务进程
searchd{
}

由于初始的配置文件有很多注释,为了简单起见,可以将那些注释都删除,以后要用到注释时可以参照sphinx.conf.dist,下面我贴出简化后的配置文件:
#主数据源(命名为main)
source main
{
    type                    = mysql

    sql_host                = localhost
    sql_user                = root
    sql_pass                = mysql
    sql_db                  = test
    sql_port                = 3306                              # optional, default is 3306
    #sql_sock               = /var/lib/mysql/mysql.sock
    sql_query_pre           = SET NAMES UTF8                    #mysql检索字符集
    sql_query_pre           = SET SESSION query_cache_type=OFF  #关闭缓存
    sql_query               = \
        SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \
        FROM documents                                          #获取数据的SQL语句
    #sql_attr_timestamp     = date_added                        #排序字段
    sql_ranged_throttle = 0
    sql_query_info      = SELECT * FROM documents WHERE id=$id  #这里的id对应于数据表的主键
}

#增量数据源(暂时用不到,先注释了)
#source src1throttled : main
#{
#   sql_ranged_throttle         = 100
#}

#主数据索引
index main
{
    source          = main                                     #指定主数据源
    path            = /usr/local/coreseek/var/data/main        #索引数据存放路径
    docinfo         = extern
    mlock           = 0
    morphology      = none

    #stopwords          = G:\data\stopwords.txt

    #wordforms          = G:\data\wordforms.txt
    #exceptions     = /data/exceptions.txt

    min_word_len        = 1
    charset_type        = utf-8
    html_strip              = 0
    #charset_table     = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44    F
}

#增量数据索引(暂时用不到)
#index test1stemmed : test1
#{
#   path            = /usr/local/coreseek/var/data/test1stemmed
#   morphology      = stem_en
#}

#分布式索引(暂时用不到)
#index dist1
#{
#   type                = distributed
#
#   local               = test1
#   local               = test1stemmed
#   agent               = localhost:9313:remote1
#   agent               = localhost:9314:remote2,remote3
#   agent_connect_timeout   = 1000
#
#   agent_query_timeout     = 3000
#}

#索引器(基本不用改)
indexer
{
    mem_limit           = 128M
}

#服务进程(不用修改)
searchd
{
    log                 = /usr/local/coreseek/var/log/searchd.log
    query_log           = /usr/local/coreseek/var/log/query.log
    read_timeout        = 5
    client_timeout      = 300

    max_children        = 30

    pid_file            = /usr/local/coreseek/var/log/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
}

在主数据源的设置中,sql_query和sql_query_info字段都是From document,这里用的是安装coreseek时提供的测试表,位于/usr/local/coreseek/etc/example.sql,根据设置,创建数据库和导入测试数据表:
mysql -uroot -pmysql
CREATE DATABASE test;
USE test;
#导入数据
SOURCE /usr/local/coreseek/etc/example.sql;
SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| documents      |
| tags           |
+----------------+
SELECT * FROM test.documents;
现在该表里面有四条数据,用该表来测试sphinx。

三、sphinx搜索测试:
1、先创建索引:在新增数据之后,都得重新索引一次
创建索引命令:indexer,
-c 指定配置文件
--all 对所有索引重新编制索引
--rotate 用于轮换索引,主要是在不停止服务的时候增加索引
--merge 合并索引

针对test:documents创建索引
vim /etc/my.cnf
query_cache_type=1
mysql -uroot -pmysql
show variables like '%query_cache_type%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| query_cache_type | ON    |
+------------------+-------+
1 row in set (0.00 sec)

#基本所有的命令都在该目录下
cd /usr/local/coreseek/bin
./indexer -c /usr/local/coreseek/etc/sphinx.conf --all

可以看到配置文件索引的是main主数据源,总共有四个文档,正好对应数据表。

2、查询关键字
查询命令:search
-c 指定配置文件

查关键字 test:
cd /usr/local/coreseek/bin
./search -c /usr/local/coreseek/etc/sphinx.conf test

查询的结果如上图所示,图中的结果表明,test 在第一篇文档中出现两次,在第二篇文档中出现两次,在第三篇文档中出现一次,总共在三个文档中出现,总共出现5次。

查关键字 group:
./search -c /usr/local/coreseek/etc/sphinx.conf group

从结果中可以发现,group只在一个文档中出现一次,但是查表发现,数据表中有group和groups,为什么groups没有被匹配出来?因为在英文分词中是以空格进行分词的,因此group和groups是两个不同的单词。

现在插入一条数据,看看能不能查询出来:
mysql -uroot -pmysql test
INSERT INTO test.documents(group_id,group_id2,date_added,title,content) VALUES(3,9,NOW(),'zhongjin','zhongjin is a student');

查关键字zhongjin
./search -c /usr/local/coreseek/etc/sphinx.conf zhongjin;
结果是mysql关键字在0个文档中出现0次,为什么?
因为没有索引该条记录,前面不是说了嘛,新增数据之后,都得重新进行索引(这个有解决方案,后面有机会再说)
./indexer -c /usr/local/coreseek/etc/sphinx.conf --all
./search -c /usr/local/coreseek/etc/sphinx.conf zhongjin;
这回出来了吧。

3、试试中文?
mysql -uroot -pmysql test
INSERT INTO test.documents(group_id,group_id2,date_added,title,content) VALUES(3,9,NOW(),'LSGO实验室','华北电力大学LSGO实验室');
./indexer -c /usr/local/coreseek/etc/sphinx.conf --all
./search -c /usr/local/coreseek/etc/sphinx.conf LSGO实验室;

从结果来看,sphinx将‘LSGO实验室’分成了‘LSGO’和‘实验室’,而且‘lsgo’被匹配出来了,但是 ‘LSGO实验室’没出来!为什么?
因为这里测试的是sphinx,仅仅对英文起作用,对中文不起作用。
下面讲对中文检索引擎进行搜索测试

根据配置建立索引文件
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf --all --rotate

启动命令
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf

然后在coreseek目录下,新建3个sh脚本,以便操作
停止服务stop.sh
#!/bin/bash
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf --stop

建立索引build.sh
#!/bin/bash
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf --all --rotate

启动服务start.sh
#!/bin/bash
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf

添加可执行权限
chmod +x start.sh
chmod +x stop.sh
chmod +x build.sh

运行start.sh后,使用crontab定时执行build.sh,就可更新索引。(注:因为数据量小且更新不算很频繁,未使用增量索引,只是定时重建主索引,新版本CoreSeek全文搜索 4.1 支持实时索引)
crontab -e
0 2 * * * sh /usr/local/coreseek/build.sh >/dev/null 2>&1
每天凌晨2点重建一次索引,忽略日志输出。

四、coreseek搜索测试
一开始是没有coreseek配置文件,建立csft.conf配置文件:
由于csft.conf配置文件中的大部分内容跟sphinx.conf的内容是一样的,仅仅要修改只是很小一部分
cd /usr/local/coreseek/etc
cp -v sphinx.conf csft.conf        #coreseek 配置文件的默认名就是csft.conf
修改 csft.conf:
1、修改字符集,将340行charset_type = utf-8 换成 charset_type = zh_cn.utf-8 (换成中文的 utf-8)
2、添加中文字典的绝对路径(直接在charset_type下面添加就可以),charset_dictpath = /usr/local/mmseg/etc/(就是你编译安装mmseg3的时候的目录下的 /etc/目录)
就是上面的两点不同,其它的设置跟 sphinx.conf 是一模一样的。
前面试图搜索关键字‘LSGO实验室’,发现搜索不了,那么现在再用那条数据测试,看看能不能搜索出来:
cd /usr/local/coreseek/bin

#重新生成索引
./indexer -c /usr/local/coreseek/etc/csft.conf --all

#搜索关键字 'LSGO实验室'
./search -c /usr/local/coreseek/etc/csft.conf LSGO实验室

结果发现关键字‘实验室’被搜索出来了!

添加一条数据再试试?
mysql -uroot -pmysql test
INSERT INTO test.documents(group_id,group_id2,date_added,title,content) VALUES(3,9,NOW(),'华北电力大学','我在华北电力大学保定校区上学呢!');

#重新生成索引
./indexer -c /usr/local/coreseek/etc/csft.conf --all

#搜索关键字 'LSGO实验室'
./search -c /usr/local/coreseek/etc/csft.conf 华北电力大学

结果证明了一切。。。。。(奇怪,‘华北电力大学’竟然不在字典里面!)
PS:如果搜索不出来,很有可能是数据表的编码的影响,因为这个测试的数据表的默认编码是latin1,要改成utf8。

五、在PHP中使用sphinx技术
在PHP中使用sphinx技术,就要做到以下几点:
1. 首先得有数据;
2. 建立sphinx配置文件
3. 生成索引
4. 启动sphinx服务进程(searchd),并开启端口9312
5. 安装PHP的sphinx扩展
6. 用PHP客户端去连接sphinx服务器
目前为止,我们就差 4 、6 还没完成,

启用sphinx服务命令:searchd
-c 指定配置文件
--stop 停止服务
--pidfile 显式指定一个PID文件
-p 指定端口

4、启动sphinx服务进程(searchd),并开启端口9312:
cd /usr/local/coreseek/bin
./searchd (或 ./search -c /usr/local/coreseek/etc/csft.conf) #这里默认加载csft.conf配置,如果配置文件不叫 csft.conf,那么可以用-c添加另外的配置文件

以上图片表示 searchd 服务开启成功,当然可以使用:
ps aux | grep searchd

netstat -tunpl | grep 9312
查看searchd的状态

6、用PHP客户端去连接sphinx服务器
[root@localhost ~]# vim /var/www/html/index.php
<?php
        $sphinx = new SphinxClient();

        //设置主机名和端口号(默认9312)
        $sphinx->SetServer("localhost",9312);

        //设置匹配的方式 SPH_MATCH_ANY表示所有的结果,SPH_MATCH_ALL表示只包含关键词的结果,举例子:搜索关键词’LSGO实验室‘,那么SPH_MATCH_ANY表示返回包含’LSGO‘的、’实验室‘的、’LSGO实验室‘的结果,而SPH_MATCH_ALL只返回包含’LSGO实验室‘的结果
        $sphinx->SetMatchMode(SPH_MATCH_ANY);

        //query('a','b');在b索引中搜索关键字a,query('a','*');在所有的索引中搜索a
        $result = $sphinx -> query("$keyword","main");

        echo "<pre>";
        print_r($result);
        echo "</pre>";

======================获取数据库中的详细信息====================
        $ids = join(',',array_keys($result['matches']));
        $mysql = new mysqli('localhost','root','mysql','test');
        $mysql->query("SET NAMES utf8");
        $sql = "SELECT * FROM documents WHERE id IN({$ids})";

        $res = $mysql->query($sql);
        while($ret = $res->fetch_assoc()){
            print_r($ret);
            echo "<br>";
        }  
?>
前面部分只是为了演示在sphinx索引中存储的值,后半部分通过搜索获取到对应字段的id,再通过这些 id 去数据库中找到它们的详细信息。



上一篇:Coreseek(Sphinx)简单应用及在LAMP中的注意事项
下一篇:RHEL 7.2安装Coreseek中文检索引擎
回复

使用道具 举报

1框架
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表