IT星球论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 363|回复: 0

Coreseek-带有中文分词的Sphinx

[复制链接]

1996

主题

1

好友

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

优秀会员 助人为乐 辛勤工作 技术精英 多才多艺 优秀班竹 灌水天才 星球管理 宣传大使 灌水之王 财富勋章 版主勋章 动漫勋章 勤奋会员 论坛精英 PS高手 心 8 闪游皮肤 双鱼座 8★8➹ 志愿者 乖

发表于 2016-3-2 12:01:27 |显示全部楼层
Coreseek-带有中文分词的sphinx
Coreseek介绍:< xmlnamespace prefix=”o”   ns=”urn:schemas-microsoft-comfficeffice”   >
Sphinx默认不支持中文索引及检索,基于Sphinx开发了Coreseek 全文检索服务器,Coreseek应该是现在用的最多的Sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg包含mmseg中文分词
(1)、下载中文分词包
http://www.coreseek.cn 到官网去下载Coreseek相应的版本
(2)、解压安装
cd /lamp
tar -zxvf coreseek-< xmlnamespace prefix=”st1″   ns=”urn:schemas-microsoft-comffice:smarttags”   >3.2.14.tar.gz
进入到mmseg所在文件夹,先安装中文分词mmseg
cd /lamp/coreseek-3.2.14/mmseg-3.2.14/
./configure –prefix=/usr/local/mmseg
编译过程中报了一个config.status: error: cannot find input file: src/Makefile.in
这个的错误,然后运行下列指令再次编译就能通过了:
automake
然后再进行编译和安装:
make && make install
然后运行mmseg,就能输入安装成功的信息了:
/usr/local/mmseg/bin/mmseg
出现下列信息,就证明mmseg中文分词已经安装好了。
< xmlnamespace prefix=”v”   ns=”urn:schemas-microsoft-com:vml”   >

接下来,我们要把Sphinx和mmseg结合起来
(1)、检测安装
进入coreseek目录,进行安装
cd /lamp/coreseek-3.2.14/csft-3.2.14/
[url=]./configure –prefix=/usr/local/coreseek –with-MySQL=/usr/local/mysql –with-mmseg=/usr/local/mmseg –with-mmseg-includes=/usr/local/mmseg/include/mmseg/ –with-mmseg-libs=/usr/local/mmseg/lib/[/url]
make && make install
(2)、配置带有中文分词的sphinx配置文件
配置文件和上面的步骤一样,只不过是在coreseek中,有几个地方需要注意。
注意:coreseek中得配置文件也是csft.conf,而不是sphinx.conf
cd  /usr/local/coreseek/etc
cp sphinx.conf.dist csft.conf
vim csft.conf
IT论坛地方都一样,对照下面不一样的地方修改
index test1
{
#stopwords                       = G:\data\stopwords.txt
#wordforms                      = G:\data\wordforms.txt
#exceptions                        = /data/exceptions.txt
#charset_type                        = sbcs
添加下面这两行,意思是把中文分词加入到配置文件中
[url=]charset_type        = zh_cn.utf-8[/url]
charset_dictpath      = /usr/local/mmseg/etc/   #你安装mmseg的目录
}
(3)、生成索引并测试
创建索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf –all
再次测试搜索中文
[url=]/usr/local/coreseek/bin/search [-a] -c /usr/local/coreseek/etc/csft.conf ‘[/url]兄弟连’

注意:如果你设置的coreseek配置文件为csft.conf,则inder、search和searchd时不用带上-c /usr/local/coreseek/etc/csft.conf,因为默认就是去寻找这个文件.
我们在linux下Sphinx,中文分词已经安装完成了,并测试成功
如何用PHP去使用Sphinx技术
在这篇中我们使用 php 程序操作 Sphinx做个小的站内搜素引擎
Sphinx集成到PHP程序中,有两种方式:
1.Sphinx php模块
2.Sphinxapi类
我们要使用 Sphinx需要做以下几件事:
1、首先得有数据
2、建立Sphinx配置文件
3、生成索引
4、启动Searchd服务进程,并开户端口9312
5、用PHP客户程序去连接Sphinx服务
一、启用sphinx服务
想要在程序中使用Sphinx必须开启Sphinx服务
启动进程命令: searchd
-c           #指定配置文件
–stop          #是停止服务
–pidfile     #用来显式指定一个 PID 文件
-p                   #指定端口
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf
注意:这里启动的服务是searchd,不是search
Sphinx默认的端口是9312端口
如果出现这个问题:
说明端口已经被占用了,解决的办法是:netstat –tunpl | grep 9312找出进程 ID,
kill -9进程id,再开启就可以了

二、用PHP连接使用Sphinx程序
(1)全PHP加载Sphinx模块
wget http://pecl.php.net/get/sphinx-1.1.0.tgz
tar zxf sphinx-1.1.0.tgz
cd /www/soft/sphinx-1.1.0
/usr/local/webserver/php/bin/phpize
./configure –with-php-config=/usr/local/webserver/php/bin/php-config
提示出错:
checking for libsphinxclient headers in default path… not found
configure: error: Cannot find libsphinxclient headers
找了下libsphinxclient,在/www/soft/csft-3.2.13/api/libsphinxclient,之前安装的是coreseek3.2.13版
cd libsphinxclient/
./configure
make && make install
安装完libsphinxclient,继续安装sphinx扩展
cd /www/soft/sphinx-1.1.0
/usr/local/php/bin/phpize
./configure –with-php-config=/usr/local/php/bin/php-config
make && make install
cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/
看到sphinx.so
vi /usr/local/webserver/php/etc/php.ini
加入extension = sphinx.so
/usr/local/apache2/bin/apachectl restart
测试Sphinx模块,http://192.168.10.1/phpinfo.php
(2)、使用API类连接Sphinx程序
需要到coreseek解压包中找到sphinxapi.php文件,放到程序目录下
cp /lamp/coreseek-3.2.14/csft-3.2.14/api/sphinxapi.php /usr/local/apache2/htdocs/
include ‘sphinxapi.php’;
//加载Sphinx API
$sphinx = new SphinxClient();
#创建sphinx对象
$sphinx->SetServer(“localhost”, 9312);
#建立连接,第一个参数sphinx服务器地址,第二个sphinx监听端口
$result = $sphinx->query($keyword,”*”);
#执行查询,第一个参数查询的关键字,第二个查询的索引名称,多个索引名称用,分开,也可以用*表示全部索引,其中包括增量索引
print_r($result);
#打印结果
找到下面这一段,是我匹配的数据
[matches] => Array ( //匹配的结果
[6] => Array
[weight] => 4
[attrs] => Array
[group_id] => 1
[date_added] => 1319127367
#一个多维的数组,下标[6]是你匹配包含关键字的文档id,id对应的数组,[weight]是权重,[attrs]是属性,我们在配置文件中指定的
这段也是我们需要的数据
[total] => 2
#此查询在服务器检索所得的匹配文档总数
[total_found] => 2
#索引中匹配文档的总数
[time] => 0.009
#这个是我们这次查询所用的时间
[words] => Array (
[兄弟] => Array
[docs] => 2  在文档中出现多少次 (content 字段中)
[hits] => 6  一共出现多少次
[连] => Array
[docs] => 2
[hits] => 6
(3)、取得数据摘要并高亮显示
Matches中就是我们匹配的结果,但是仿佛不是我们想要的数据,比如 titile,content字段的内容就没有匹配出来,根据官方的说明是 Sphinx 并没有连接到 MySQL去取数据,只是根据它自己的索引内容进行计算,因此如果想用 Sphinx 提供的API 去取得我们想要的数据,还必须以查询的结果为依据,再次查询 MySQL从而得到我们想要的数据
比如:
$mysqli = new mysqli(“localhost”,”root”,”password”,”test”);
$ids= join(‘,’,array_keys($result['matches'])); 要把需要的id取出来。
$sql=”select title,content from post where id in({$ids})”;
$result=$mysqli->query($sql);
while($row=$result->fetch_row()){
#循环体开始解析看下结果.
下面我们在输出结果的时候需要生成摘要,高亮(就是和百度一样,关键字飘红)我们需要用到 buildExcerpts 这个函数,(php 手册中)语法格式:
public array SphinxClient::buildExcerpts ( array $docs , string $index , string
$words [, array $opts ])
#返回的是一个数组,一共有四个参数
#第一个参数是从数据库中查询的结果集
#第二个参数是索引的名字
#第三个参数是要高亮显示的关键字
#第四个参数是显示的字 格式化
$opts = array(
#格式化摘要,高亮字体设置
#在匹配关键字之前插入的字符串,默认是<b>
“before_match”  => “<span style=’font-weight:bold;color:red’>”,
#在匹配关键字之后插入的字符串,默认是</b>
“after_match”  => “</span>”,
#在摘要段落之前插入的字符串默认 „
“chunk_separator” => ” … “,
);
$res=$sphinx->buildExcerpts($row,”index”,$keyword,$opts);
echo “<font size=4>”.$res[0].”</font></a></br>”; 标题
echo “<font size=2>”.$res[1].”</font></br>”;  摘要
echo $res[2].”</p>”;  添加时间
}
#循环体结束
到这里呢,我们用php程序调用sphinxapi实现了高亮摘要功能
三、匹配模式
匹配模式:SetMatchMode(设置匹配模式)
原型:function SetMatchMode ( $mode )
SPH_MATCH_ALL 匹配所有查询词(默认模式).
SPH_MATCH_ANY 匹配查询词中的任意一个.
SPH_MATCH_PHRASE 将整个查询看作一个词组,要求按顺序完整匹配.
SPH_MATCH_BOOLEAN 将查询看作一个布尔表达式.
SPH_MATCH_EXTENDED 将查询看作一个 Sphinx 内部查询语言的表达式.
SPH_MATCH_FULLSCAN 使用完全扫描,忽略查询词汇.
SPH_MATCH_EXTENDED2 类似 SPH_MATCH_EXTENDED ,并支持评分和权重
四、Sphinx实时索引
数据库中的数据很大,然后我有些新的数据后来加入到数据库中,也希望能够检索到,全部重新建立索引很消耗资源,这样需要用到“主索引+增量索引”的思路来解决,这个模式实现的基本原理是设置两个数据源和两个索引。
1、创建一个计数器
一个简单的实现是,在数据库中增加一个计数表,记录将文档集分为两个部分的文档 ID,每次重新构建主索引时,更新这个表
先在 mysql 中插入一个计数表
CREATE TABLE sph_counter( counter_id INTEGER PRIMARY KEY NOT NULL,    max_doc_id INTEGER NOT NULL);
2、再次修改配置文件
主数据源,继承数据源,主索引,继承索引。(继承索引也就是增量索引)。
主数据源里面:我们需要把欲查询语句改成下面的语句:
Vi /usr/local/coreseek/etc/csft.conf
Source main{
把sql_query_pre的改成下面的语句
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM post
sql_query=    \
SELECT id,title, content FROM post \
WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
}
继承数据源:
source delta : main
{
sql_query_pre = SET NAMES utf8
sql_query
= \
SELECT id,title, content FROM post \
WHERE id>(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
}
主索引:
把名字该成想对应的
Index main {
source  = main
path = /usr/local/coreseek/var/data/main
}
继承索引(也是增量索引)
index delta:main
{
source= delta
path= /usr/local/coreseek/var/data/delta
}
剩下的基本不用改变
注意:如果你增量索引的 source 配置中只有 id,content 三项
而主索引的 source 配置中有 id, title,content 四项,合并的时候会报属性数量不匹配,如:
Delta:sql_query = SELECT id, title,content FROM post
Main:sql_query=SELECT id,title,date,content FROM post
3、测试增量索引+主索引
如果想测试增量索引是否成功,往数据库表中插入数据,查找是否能够检索到,这个时候检索应该为空,然后,单独重建增量索引
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf delta
查看是否将新的记录进行了索引,如果成功
此时,再用/usr/local/coreseek/bin/search 工具来检索,能够看到,在主索引中检索到的结果为 0,而在增量中检索到结果。当然,前提条件是,检索的词,只在后来插入的数据中存在
4、实时更新索引
我们需要建立两个脚本,还要用到计划任务
建立一个主索引和增量索引的脚本
main.sh  delta.sh
在增量索引中写下delta.sh
#!/bin/bash
#delta.sh
/usr/local/coreseek/bin/indexer delta >>/usr/local/coreseek/var/log/delta.log
主索引中写下:main.sh意思就是合并索引
#!/bin/bash
#main.sh
/usr/local/coreseek/bin/indexer main >>/usr/local/coreseek/var/log/merge.log
最后,我们需要脚本能够自动运行,以实现增量索引每5分钟重新建立,和主索引只在凌晨2:30时重新建立.
脚本写好了,我们需要建立计划任务
crontab -e
*/10 * * * *  /usr/local/coreseek/etc/delta.sh
30 2 * * *  /usr/local/coreseek/etc/main.sh
第一条是表示每5分钟运行
第二条是表示每天的凌晨2:30分运行
脚本权限:
chmod a+x delta.sh
chmod a+x main.sh
要验证的话,我们可以查看日志文件
五、分布式索引
分布式是为了改善查询延迟问题和提高多服务器、多 CPU 或多核环境下的吞吐率,对于大量数据(即十亿级的记录数和 TB 级的文本量)上的搜索应用来说是很关键的
分布式思想:对数据进行水平分区(HP,Horizontally partition),然后并行处理,
当searchd收到一个对分布式索引的查询时,它做如下操作
1. 连接到远程代理.
2. 执行查询.
3. 对本地索引进行查询.
4. 接收来自远程代理的搜索结果.
5. 将所有结果合并,删除重复项.
6. 将合并后的结果返回给客户端.
index dist
{
type = distributed
local = chunk1
agent = localhost:9312:chunk2    本地
agent = 192.168.100.2:9312:chunk3   远程
agent = 192.168.100.3:9312:chunk4   远程
}
Sphinx我们已经基本讲完,主要讲解了包括 Sphinx、中文分词、高亮、摘要、匹配、增量索引、实时索引和分布式索引等方面的知识.
六.PHP代码实例:
Vi index.php
  1. <html>

  2. <head>

  3.    <meta http-equiv="content-type" content="text/html; charset=utf-8">

  4. </head>

  5. <body>

  6.    <h1>简单PHP搜索测试</h1>

  7.    <form action="find.php" method=post>

  8.          请输入搜索关键字:<input type="text" name="word">


  9.          <input type="submit" name="submit">


  10.    </form>

  11. </body>

  12. </html>

  13. Vi find.php

  14. <html>

  15. <head>

  16.    <meta http-equiv="content-type" content="text/html; charset=utf-8">

  17.    <title>Find</title>

  18. </head>

  19. <body>

  20.    <h1 id='top'>查询输出页面</h1>

  21.    <?php

  22.        $keyword=$_POST['word'];  

  23.        $sphinx=new SphinxClient();

  24.        $sphinx->SetServer("localhost",9312);

  25.        $sphinx->SetMatchMode(SPH_MATCH_ANY);

  26.        //$sphinx->setLimits(0,0);

  27.        $result=$sphinx->query("$keyword","*");

  28.        //echo "<pre>";

  29.        //print_r($result);

  30.        //echo "</pre>";

  31.        $ids=join(",",array_keys($result['matches']));

  32.        mysql_connect("localhost","root","123");

  33.       mysql_select_db("test");

  34.        $sql="select * from post where id in({$ids})";

  35.        mysql_query("set names utf8");

  36.        $rst=mysql_query($sql);

  37.        $opts=array(

  38.            "before_match"=>"<button style='font-weight:bold;color:#f00'>",

  39.           "after_match"=>"</button>"

  40.        );

  41.        while($row=mysql_fetch_assoc($rst)){

  42.            $rst2=$sphinx->buildExcerpts($row,"main",$keyword,$opts);

  43.            echo "第{$rst2[0]}篇贴子
  44. ";

  45.            echo "标题: {$rst2[1]}
  46. ";

  47.            echo "内容: {$rst2[2]}
  48. ";

  49.            echo "<hr>";

  50.        }

  51.    ?>

  52. <body>

  53. <html>
复制代码
http://www.it163.org/post/118fd1_303315


Coreseek-带有中文分词的Sphinx

该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

回顶部