之前看过一篇文章:全文搜索和中文分词
主要是介绍PHP的两种搜索:
- Elasticsearch + IK Analyzer 完全独立;
- TNTSearch + jieba-php 完全基于 php ;
于是我选择了第二种方式试了一下,安装jieba-php倒是没啥问题,而TNTSearch需要SQLite存储索引,在这里配置出错,所以就搁置了。。。改天再仔细研究一下把。(该篇文章的博主已经写了基于laravel的搜索,所以用laravel的童鞋们可以参考下!)
于是我把搜索相关的都找了找,于是就有了这篇文章:XunSearch(http://www.xunsearch.com/),安装分为两部分:1.服务器上的安装可根据官网的来,写的比较详细,其中需要注意的是: 开启/重新开启 xunsearch 服务程序,命令如下:/usr/local/xunsearch/bin/xs-ctl.sh restart 强烈建议将此命令写入服务器开机脚本中。2.php-sdk包,我使用的是composer安装的,packagist上搜索就有,当然XunSearch官网文档上面也有。XunSearch很多基本语法的使用,文档写的比较清楚了。我这里仅列出部分常用的几个:
搜索中的串接操作
支持串接操作的方法有:
- addDB($name) - 用于多库搜索,添加数据库名称
- addRange($field, $from, $to) - 添加搜索过滤区间或范围
- addWeight($field, $term) - 添加权重索引词
- setCharset($charset) - 设置字符集
- setCollapse($field, $num = 1) - 设置搜索结果按字段值折叠
- setDb($name) - 设置搜索库名称,默认则为 db
- setFuzzy() - 设置开启模糊搜索, 传入参数 false 可关闭模糊搜索
- setLimit($limit, $offset = 0) - 设置搜索结果返回的数量和偏移
- setQuery($query) - 设置搜索语句
- setSort($field, $asc = false) - 设置搜索结果按字段值排序
type 字段类型
- string 字符型,适用多数情况,也是默认值
- numeric 数值型,包含整型和浮点数,仅当字段需用于以排序或区间检索时才设为该类型,否则请使用 string 即可
- date 日期型,形式为 YYYYmmdd 这样固定的 8 字节,如果没有区间检索或排序需求不建议使用
- id 主键型,确保每条数据具备唯一值,是索引更新和删除的凭据,每个搜索项目必须有且仅有一个 id 字段,该字段的值不区分大小写
- title 标题型,标题或名称字段,至多有一个该类型的字段
- body 内容型,主内容字段, 即本搜索项目中内容最长的字段,至多只有一个该类型字段,本字段不支持字段检索
搜索使用:
这里以article为例,mysql里的数据和xunsearch 里的是一致的!
//xunsearch与mysql对比搜索--完成
public function search()
{
try {
//1.-----------数据库查询----------
$where = " 1 = 1 ";
$keywords = trim(I('keywords'));
$where.=" and title like '%$keywords%' ";
$list = Db::name('article')
->field('article_id,title,content,add_time')
->where($where)
->select();
print_r($list);exit;
//2.-----------xunsearch查询------------
$xs = new \XS('article'); // 建立 XS 对象,项目名称为:article
$docs = $xs->search->setQuery('支付')->search();
foreach ($docs as $k=> $doc){
$result[$k]['article_id'] = $doc->article_id;
$result[$k]['title'] = $doc->title;
$result[$k]['content'] = $doc->content;
$result[$k]['add_time'] = $doc->add_time;
}
print_r($result);exit;
} catch (\XSException $e) {
echo $e; // 直接输出异常描述
if (defined('DEBUG')) // 如果是 DEBUG 模式,则输出堆栈情况
echo "\n" . $e->getTraceAsString() . "\n"; // 发生异常,输出描述
}
}
上面两种方式均可以搜索,且结果是一样的。(排序可能不通,应该这里未设置排序,两种方式都是默认的排序)
打印结果:
Array
(
[0] => Array
(
[article_id] => 10
[title] => 支付宝支付
[content] => <p>支付宝支付</p>
[add_time] => 20170906
)
[1] => Array
(
[article_id] => 9
[title] => 银联支付
[content] => <p>是的发送到</p>
[add_time] => 20170906
)
[2] => Array
(
[article_id] => 11
[title] => 微信支付
[content] => <p>水电费水电费</p>
[add_time] => 20170906
)
[3] => Array
(
[article_id] => 12
[title] => 余额支付
[content] => <p>是的发送到水电费</p>
[add_time] => 20170906
)
)
这里使用apache进行压测,如下图:
《图一》
《图二》
图一是php+mysql,图二是xunsearch,可以发现:xunsearch的搜索速度快!抗压性好!这里是相对简单的搜索,更复杂一些的搜索有待我们去验证。