发布时间:2020/11/13 作者:天马行空 阅读(1526)
Xunsearch 是免费开源的专业全文检索解决方案,旨在帮助一般开发者针对既有的海量数据,快速而方便地建立自己的全文搜索引擎。全文检索可以帮助您降低服务器搜索负荷、极大程度的提高搜索速度和用户体验。
高性能:后端是采用 C/C++ 开发多线程服务端,索引设计基于 Xapian 和 scws 中文分词。单库最多支持 40 亿条数据,在 5 亿网页大约 1.5TB 的数据中检索时间不超过 1 秒(非缓存)。
简单易用:前端是使用脚本语言编写的开发工具 (SDK),目前仅支持 PHP 语言。API 简单清晰,开发难度极低,提供全中文的示例代码、文档、辅助脚本工具等。
全功能:除支持基础的自定义分词、字段检索、布尔搜索外,还直接支持用户急需的相关搜索、拼音搜索、搜索建议等专业功能。
一、安装Xunsearch服务端
[root@iZ2vcdckpocdmc9n3vlbywZ ~]# yum install -y bzip2 [root@iZ2vcdckpocdmc9n3vlbywZ ~]# wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2 [root@iZ2vcdckpocdmc9n3vlbywZ ~]# tar -xjf xunsearch-full-latest.tar.bz2 [root@iZ2vcdckpocdmc9n3vlbywZ ~]# cd xunsearch-full-1.4.14/ [root@iZ2vcdckpocdmc9n3vlbywZ ~]# sh setup.sh [root@iZ2vcdckpocdmc9n3vlbywZ ~]# cd /home/wwwroot/xunsearch/ [root@iZ2vcdckpocdmc9n3vlbywZ xunsearch]# bin/xs-ctl.sh -b inet start
二、通过composer安装php搜索包
composer require hightman/xunsearch
三、编写项目配置文件xunseach.ini
具体规则请参考:http://www.xunsearch.com/doc/php/guide/ini.guide
; 项目名称 project.name = article ; 默认字符集 project.default_charset = utf-8 ; 索引服务端配置,默认值为 8383 server.index = 127.0.0.1:8383 ; 搜索服务端配置,默认值为 8384 server.search = 127.0.0.1::8384 [id] ; 字段类型 type = id [title] type = title [description] type = string index = mixed [content] type = body [sort] type = numeric [publish_time] type = numeric
四、生成索引
生成索引是将你数据库中的数据按照一定规则查询出来,然后添加到xunsearch的索引中去,这需要增加一个定时的计划任务,将新增的数据不断的添加进去,才能通过api搜索出来结果。以下的基于thinkphp写的添加索引的一段代码,理解思路即可。
/**
* 生成索引
* @return mixed|string
*/
public function index()
{
//每两分钟执行一次
//*/2 * * * * /xxxxx/php /xxx/task/index.php article/index 2
$minute = isset($GLOBALS["argv"][2]) ? (int)$GLOBALS["argv"][2] : 0;
$where = [
['status','=',1],
];
if ($minute) {
$where[] = ['updated','>',time()-$minute*60];//多少分钟之前更新的
}
ArticleModel::where($where)->chunk(500,function($rows) {
$datas = [];
foreach ($rows as $row){
$datas[] = [
'id' => $row->id, // 此字段为主键,是进行文档替换的唯一标识
'title' => $row->title,
'description' => $row->description,
'content' => strip_tags($row->content),
'sort' => $row->sort,
'publish_time' => $row->publish_time
];
}
$this->addIndex($datas);
},'id','asc');
die('success');
}
private function addIndex($datas){
try
{
//实例化xunsearch对象
$xs = new \XS('article');
//使用索引缓冲区
$xs->index->openBuffer();
foreach ($datas as $data){
// 创建文档对象
$doc = new \XSDocument;
$doc->setFields($data);
// 更新到索引数据库中
$xs->index->update($doc);
}
//告诉服务器重建索引完成
$xs->index->closeBuffer();
}
catch (\XSException $e)
{
//echo $e; // 直接输出异常描述
if (defined('DEBUG')) // 如果是 DEBUG 模式,则输出堆栈情况
echo "\n" . $e->getTraceAsString() . "\n";
}
}
五、搜索功能实现
搜索文档请参考:http://www.xunsearch.com/doc/php/guide/search.overview
public function search(){
$datas = [];
$keywords = $this->request->param('keywords');
$page = $this->request->param('page',1);
$limit = 10;//每页多少条
$count = 0;//搜出来多少条
$pageLink = '';//分页代码
if ($keywords) {
$xs = new \XS('article');
$search = $xs->search; // 获取 搜索对象
$tokenizer = new \XSTokenizerScws; // 创建分词实例
$words = $tokenizer->getTokens($keywords);//分词
$search->setQuery(join(' OR ', $words))->setFuzzy(true);//设置查询条件
//解决统计总条数不准确的问题:始终都用最后一页的总条数
$search->search();
$count1 = $search->getLastCount();
$page1 = ceil($count1/$limit);
$search->setLimit($limit,($page1-1)*$limit)->search();
$count = $search->getLastCount();
$docs = $search->setLimit($limit, $offset=(($page-1)*$limit))->setSort('publish_time')->search();
foreach ($docs as &$doc)
{
$datas[] = [
'id'=>$doc->id,
'title'=>$doc->title,
'description'=>$doc->description,
'title_h'=>$search->highlight($doc->title,false), // 高亮处理 title 字段
'description_h'=>$search->highlight($doc->description,false), // 高亮处理 description 字段
//'content'=>$doc->content,
'sort'=>$doc->sort,
'publish_time'=>$doc->publish_time,
];
}
if ($count>0){
$pageLink = Bootstrap::make(null, $limit, $page, $count, false, ['path'=>'', 'query'=>['keywords'=>$keywords]])->render();
}
}
$this->assign('keywords',$keywords);
$this->assign('count',$count);
$this->assign('pageLink',$pageLink);
$this->assign('datas',$datas);
return $this->fetch('Article/Article-search');
}