共计 10078 个字符,预计需要花费 26 分钟才能阅读完成。
前言:
在本文中我将给大家带来 Coreseek(Sphinx)在 PHP 中的一个简单的例子、并在后面给大家讲一下 Coreseek(Sphinx)在 LAMP 环境中的一些注意事项,比如 searchd 的开机启动呀,Sphinx 实时索引啊。
有关 coreseek(sphinx)在 LAMP 上的安装以及配置、使用大家请参考我之前的两篇博客:
- CentOS 7 下安装 Coreseek 中文检索引擎 http://www.linuxidc.com/Linux/2017-05/143599.htm
- LAMP+Coreseek 中文检索引擎使用详解 http://www.linuxidc.com/Linux/2017-05/143600.htm
PS:这里用到的数据库和数据表都是在前面两篇博客中创建的。
一、coreseek+mysql+php 的一个简单使用:模拟搜索引擎
1、创建搜索首页:index.php
<html>
<head>
<title>测试搜索</title>
</head>
<body>
<h1>简单 PHP 搜索引擎</h1>
<form action='find.php' method='post'>
请输入搜索关键字:<input type='text' name='find'><br>
<input type='submit' value='提交搜索关键字'>
</form>
</body>
</html>
效果:
2、处理并显示搜索结果页面:find.php
<html>
<head><title>Result</title></head>
<body>
<h1>搜索结果展示 www.linuxidc.com</h1>
<?php
$keyword = $_POST['find'];
$sphinx = new SphinxClient();
// 设置主机和端口号
$sphinx->SetServer("localhost",9312);
// 搜索匹配方案
$sphinx->SetMatchMode(SPH_MATCH_ANY);
//query('a','b'); 在 b 索引中搜索关键字 a,* 表示所有索引
$result = $sphinx -> query("$keyword","*");
$ids = join(',',array_keys($result['matches']));
$mysql = new mysqli('localhost','root','zhongjin','test');
$mysql->query("SET NAMES utf8");
$sql = "SELECT * FROM documents WHERE id IN({$ids})";
$res = $mysql->query($sql);
$count = $res->num_rows;
// 该数组设置搜索关键字的显式样式
/*
$opts = array(
'before_match' => "<font style='font-weight:bold;color:#f00'>",
'after_match' => "</font>",
);
*/
$opts = array('before_match' => "<button style='font-weight:bold;color:#f00'>",
'after_match' => "</button>",
);
if($count > 0){while($ret = $res->fetch_assoc()){// 使搜索关键字高亮显示
$row = $sphinx -> buildExcerpts($ret,'main',$keyword,$opts);
echo "标题:{$row[4]}<br>";
echo "内容:{$row[5]}";
echo "<hr>";
}
echo "搜索结果 {$count} 条。";
}else{echo "无搜索结果!";
}
?>
</body>
</html>
当我搜索’LSGO 实验室‘时,效果如下:
这就是 sphinx+MySQL+php 的一个简单应用,以及使搜索关键字高亮显示。
二、sphinx 的实时索引
1、为什么要实现 sphinx 实时索引?
看看 coreseek 增量索引模拟实时索引 http://www.linuxidc.com/Linux/2017-05/143601.htm,在这里就引用该篇文章的内容:
有这么一种常见的情况:整个数据集非常大,以至于难于经常性的重建索引,但是每次新增的记录却相当地少。一个典型的例子是:一个论坛有 1000000 个已经归档的帖子,但每天只有 1000 个新帖子。
在这种情况下可以用所谓的“主索引+增量索引”(main+delta)模式来实现“近实时”的索引更新。
这种方法的基本思路是设置两个数据源和两个索引,对很少更新或根本不更新的数据建立主索引,而对新增文档建立增量索引。在上述例子中,那 1000000 个已经归档的帖子放在主索引中,而每天新增的 1000 个帖子则放在增量索引中。增量索引更新的频率可以非常快,而文档可以在出现几分种内就可以被检索到。
确定具体某一文档的分属那个索引的分类工作可以自动完成。一个可选的方案是,建立一个计数表,记录将文档集分成两部分的那个文档 ID,而每次重新构建主索引时,这个表都会被更新。
这里再用我的理解跟大家陈述一遍(如果大家有看我的前面两篇博客,这里会看的非常明白):
在前面我有一张 documents 表,现在我要往里面添加一篇文章,我想使这篇文章被检索到,就要执行
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf --all --rotate
,要想减少能够检索的时间,我们可以使用 crontab 实现每分钟执行一次该命令。然而这条命令是把整张表重新建立主数据索引,假如该表现在已经有好几千万条数据了,如果把整张表的数据重新建立索引,就会大量的消耗服务器 CPU 和内存。
上面说的解决方案就是,我能不能仅仅对今天新增的数据建立索引,主数据索引保持不变?毕竟一天内新增的数据不会太多。
这里实现的办法就是“主索引 + 增量索引”,原来的数据保存在主索引里面,而新增的数据就保存在增量索引里面,在服务器空闲的时候(一般在凌晨),在将增量索引并到主索引中去,这样就不会影响到第二天的建立增量索引。
2、建立计数表
该表的作用是记录将文档集分成两部分的那个文档 ID(一部分保存在主数据索引,一部分保存在增量索引),其实就是昨晚将增量索引并入主数据索引时 documents 数据表的 id 的最大值,而每次重新构建主索引时,这个表都会被更新。
创建计数表:
mysql -uroot -pzhongjin test;
CREATE TABLE sph_counter(counter_id INT PRIMARY KEY NOT NULL,
max_doc_id INT NOT NULL
);
3、修改配置文件 csft.conf
在修改配置文件之前,给大家说一下 mysql 中的 REPLACE INTO 的用法:
使用 REPLACE INTO 的时候会带上一个主键,假如目标数据表中对应的该主键没有数据,那么 REPLACE INTO 就会往里面插数据(相当于 INSERT INTO)。假如该主键已经有数据了,REPLACE INTO 就会更新该条数据。
修改配置文件 csft.conf:
#1、在主数据源中(source main{})修改:
#新增一行,作用是更新 sph_counter 表
sql_query_pre = REPLACE INTO sph_counter SELECT 1,MAX(id) FROM documents;
#2、将增量数据源(source src1throttled : src1{})的注释打开
#修改增量数据源名字并添加如下内容:source delta : main{
sql_ranged_throttle = 100
sql_query_pre = SET NAMES UTF8
sql_query = \
SELECT id,group_id,UNIX_TIMESTAMP(date_added) AS date_added,title,content FROM \
documents WHERE id > (SELECT max_doc_id FROM sph_counter WHERE counter_id = 1)
}
3、将增量数据索引(index test1stemmed : test1){})的注释打开
#修改增量数据索引名字并添加如下内容:index delta : main
{
source = delta
path = /usr/local/coreseek/var/data/delta
morphology = stem_en
}
注意:增量数据源的 sql 语句搜索出来的结果字段一定要与主数据源的对称,因为他俩是继承关系,如果不对称,就会报错:字段不统一
更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-05/143603p2.htm
4、测试增量索引 + 主索引
到目前为止,sph_counter 表是空的,现在我们执行更新索引命令:
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf --all --rotate
–all 表示生成所有索引,包括主数据索引(main)和增量数据索引(delta)
–rotate 是因为由于现在 searchd 服务在进行,必须加该参数
图中可以看到,该命令创建更新了两个索引(main 和 delta),这时候我们再看看 sph_counter 表和 documents 表:
mysql -uroot -pzhongjin test
SELECT * FROM sph_counter;
SELECT id,title,content FROM documents;
可以看到,现在 sph_countter 表中保存的是 documents 表中的 id 的最大值。
================== 分割线 ====================
往 documents 表中插入一条数据,
INSERT INTO documents(group_id,group_id2,date_added,title,content) VALUES(4,10,NOW(),'LINUX 技术','在华北电力大学 LSGO 实验室学习 LINUX 技术');
按照前面说的,对新增数据建立增量索引,而不是对索引数据重新建立主数据索引:
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf delta --rotate
ps:假如对单个类型建立索引,直接用索引名代替 –all , 例如为主数据源建立主数据索引,/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf main --rotate
================== 分割线 ====================
我们搜索‘Linux’试试:
/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/csft.conf LINUX
发现结果是来自增量索引 delta 的。也就是说现在主数据索引里面是不包含该条数据的。
PS:假如现在你在 PHP 中使用 sphinx 技术的话,在搜索关键字的时候,一定要用 $sphinx -> query("{$keyword}","*")
, 因为“*”表示所有的索引,而不仅仅是主数据索引。
最后我们还要实现将增量索引合并到主数据索引中去,再将 sph_counter 表的 max_doc_id 字段更新。
5、用 crontab 实现定时建立增量索引和主数据索引
我们将建立增量索引和主数据索引的命令写成一个可执行脚本,放到 /usr/local/coreseek/etc/init 下:
cd /usr/local/coreseek/etc
mkdir init
cd init
# 建立主数据索引脚本
touch main.sh
# 建立增量数据索引脚本
touch delta.sh
# 添加权限:
chmod 755 *.sh
添加日志文件,方便以后查阅
cd /usr/local/coreseek/var/log
# 建立主数据索引日志文件
touch main.log
# 建立增量数据索引脚本
touch delta.log
# 添加权限
chmod 755 main.log delta.log
往 main.sh 添加以下内容:
#!/bin/bash
# main.sh
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf main --rotate >> /usr/local/coreseek/var/log/main.log
echo "==============================================================" >> /usr/local/coreseek
/var/log/main.log
往 delta.sh 添加以下内容:
#!/bin/bash
# delta.sh
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf delta --rotate >> /usr/local/coreseek/var/log/delta.log
echo "==============================================================" >> /usr/local/coreseek
/var/log/delta.log
==================================================
我们的目标是:每五分钟创建一次增量索引,每天凌晨三点合并增量索引,重建主数据索引。
使用 crontab 定时执行 main.sh 和 delta.sh
crontab -e
# 添加以下两行
*/5 * * * * /usr/local/coreseek/etc/init/delta.sh
00 03 * * * /usr/local/coreseek/etc/init/main.sh
好了,现在 sphinx 的实时索引就算是完成了。
三、配置 searchd 的开机自启:
1、原理:
系统开机启动时会去加载 /etc/init.d/ 下面的脚本,通常而言每个脚本文件会自定义实现程序的启动;若想将新的程序开机自启动,只需在该目录下添加一个自定义启动程序的脚本,然后设置相应规则即可。
如在这里我们在 /etc/init.d/ 下新建一个 auto_coreseek 的脚本,开机启动时会去加载执行该脚本
2、编写开机启动脚本:
创建脚本 auto_coreseek
cd /etc/init.d
vim auto_coreseek
在 auto_coreseek 中添加以下内容:
#!/bin/sh
#chkconfig:2345 80 90
#description:auto_coreseek
/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf
添加权限:
chmod 755 auto_coreseek
启动测试:
# 先把该进程关掉
killall searchd
/etc/init.d/auto_coreseek start
添加到开机启动项:
chkconfig auto_coreseek on
重启服务器测试:
reboot
ps aux | grep searchd
# 或
netstat -tunlp | 9312
好了,完成!
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-05/143603.htm
前言:
在本文中我将给大家带来 Coreseek(Sphinx)在 PHP 中的一个简单的例子、并在后面给大家讲一下 Coreseek(Sphinx)在 LAMP 环境中的一些注意事项,比如 searchd 的开机启动呀,Sphinx 实时索引啊。
有关 coreseek(sphinx)在 LAMP 上的安装以及配置、使用大家请参考我之前的两篇博客:
- CentOS 7 下安装 Coreseek 中文检索引擎 http://www.linuxidc.com/Linux/2017-05/143599.htm
- LAMP+Coreseek 中文检索引擎使用详解 http://www.linuxidc.com/Linux/2017-05/143600.htm
PS:这里用到的数据库和数据表都是在前面两篇博客中创建的。
一、coreseek+mysql+php 的一个简单使用:模拟搜索引擎
1、创建搜索首页:index.php
<html>
<head>
<title>测试搜索</title>
</head>
<body>
<h1>简单 PHP 搜索引擎</h1>
<form action='find.php' method='post'>
请输入搜索关键字:<input type='text' name='find'><br>
<input type='submit' value='提交搜索关键字'>
</form>
</body>
</html>
效果:
2、处理并显示搜索结果页面:find.php
<html>
<head><title>Result</title></head>
<body>
<h1>搜索结果展示 www.linuxidc.com</h1>
<?php
$keyword = $_POST['find'];
$sphinx = new SphinxClient();
// 设置主机和端口号
$sphinx->SetServer("localhost",9312);
// 搜索匹配方案
$sphinx->SetMatchMode(SPH_MATCH_ANY);
//query('a','b'); 在 b 索引中搜索关键字 a,* 表示所有索引
$result = $sphinx -> query("$keyword","*");
$ids = join(',',array_keys($result['matches']));
$mysql = new mysqli('localhost','root','zhongjin','test');
$mysql->query("SET NAMES utf8");
$sql = "SELECT * FROM documents WHERE id IN({$ids})";
$res = $mysql->query($sql);
$count = $res->num_rows;
// 该数组设置搜索关键字的显式样式
/*
$opts = array(
'before_match' => "<font style='font-weight:bold;color:#f00'>",
'after_match' => "</font>",
);
*/
$opts = array('before_match' => "<button style='font-weight:bold;color:#f00'>",
'after_match' => "</button>",
);
if($count > 0){while($ret = $res->fetch_assoc()){// 使搜索关键字高亮显示
$row = $sphinx -> buildExcerpts($ret,'main',$keyword,$opts);
echo "标题:{$row[4]}<br>";
echo "内容:{$row[5]}";
echo "<hr>";
}
echo "搜索结果 {$count} 条。";
}else{echo "无搜索结果!";
}
?>
</body>
</html>
当我搜索’LSGO 实验室‘时,效果如下:
这就是 sphinx+MySQL+php 的一个简单应用,以及使搜索关键字高亮显示。
二、sphinx 的实时索引
1、为什么要实现 sphinx 实时索引?
看看 coreseek 增量索引模拟实时索引 http://www.linuxidc.com/Linux/2017-05/143601.htm,在这里就引用该篇文章的内容:
有这么一种常见的情况:整个数据集非常大,以至于难于经常性的重建索引,但是每次新增的记录却相当地少。一个典型的例子是:一个论坛有 1000000 个已经归档的帖子,但每天只有 1000 个新帖子。
在这种情况下可以用所谓的“主索引+增量索引”(main+delta)模式来实现“近实时”的索引更新。
这种方法的基本思路是设置两个数据源和两个索引,对很少更新或根本不更新的数据建立主索引,而对新增文档建立增量索引。在上述例子中,那 1000000 个已经归档的帖子放在主索引中,而每天新增的 1000 个帖子则放在增量索引中。增量索引更新的频率可以非常快,而文档可以在出现几分种内就可以被检索到。
确定具体某一文档的分属那个索引的分类工作可以自动完成。一个可选的方案是,建立一个计数表,记录将文档集分成两部分的那个文档 ID,而每次重新构建主索引时,这个表都会被更新。
这里再用我的理解跟大家陈述一遍(如果大家有看我的前面两篇博客,这里会看的非常明白):
在前面我有一张 documents 表,现在我要往里面添加一篇文章,我想使这篇文章被检索到,就要执行
/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/csft.conf --all --rotate
,要想减少能够检索的时间,我们可以使用 crontab 实现每分钟执行一次该命令。然而这条命令是把整张表重新建立主数据索引,假如该表现在已经有好几千万条数据了,如果把整张表的数据重新建立索引,就会大量的消耗服务器 CPU 和内存。
上面说的解决方案就是,我能不能仅仅对今天新增的数据建立索引,主数据索引保持不变?毕竟一天内新增的数据不会太多。
这里实现的办法就是“主索引 + 增量索引”,原来的数据保存在主索引里面,而新增的数据就保存在增量索引里面,在服务器空闲的时候(一般在凌晨),在将增量索引并到主索引中去,这样就不会影响到第二天的建立增量索引。
2、建立计数表
该表的作用是记录将文档集分成两部分的那个文档 ID(一部分保存在主数据索引,一部分保存在增量索引),其实就是昨晚将增量索引并入主数据索引时 documents 数据表的 id 的最大值,而每次重新构建主索引时,这个表都会被更新。
创建计数表:
mysql -uroot -pzhongjin test;
CREATE TABLE sph_counter(counter_id INT PRIMARY KEY NOT NULL,
max_doc_id INT NOT NULL
);
3、修改配置文件 csft.conf
在修改配置文件之前,给大家说一下 mysql 中的 REPLACE INTO 的用法:
使用 REPLACE INTO 的时候会带上一个主键,假如目标数据表中对应的该主键没有数据,那么 REPLACE INTO 就会往里面插数据(相当于 INSERT INTO)。假如该主键已经有数据了,REPLACE INTO 就会更新该条数据。
修改配置文件 csft.conf:
#1、在主数据源中(source main{})修改:
#新增一行,作用是更新 sph_counter 表
sql_query_pre = REPLACE INTO sph_counter SELECT 1,MAX(id) FROM documents;
#2、将增量数据源(source src1throttled : src1{})的注释打开
#修改增量数据源名字并添加如下内容:source delta : main{
sql_ranged_throttle = 100
sql_query_pre = SET NAMES UTF8
sql_query = \
SELECT id,group_id,UNIX_TIMESTAMP(date_added) AS date_added,title,content FROM \
documents WHERE id > (SELECT max_doc_id FROM sph_counter WHERE counter_id = 1)
}
3、将增量数据索引(index test1stemmed : test1){})的注释打开
#修改增量数据索引名字并添加如下内容:index delta : main
{
source = delta
path = /usr/local/coreseek/var/data/delta
morphology = stem_en
}
注意:增量数据源的 sql 语句搜索出来的结果字段一定要与主数据源的对称,因为他俩是继承关系,如果不对称,就会报错:字段不统一
更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-05/143603p2.htm