据说,XunSearch是开源免费、高性能、多功能、简单易用的全文检索技术方案 !刚好弄了个[看小说的网站](http://book.haolie.net "看小说的网站"),有些内容,可以用来测试一下。感觉没必要对章节内容进行索引,就只对书目和简介处理一下。 ## 安装 懒得下载以及折腾依赖关系,直接使用Docker安装。安装时将Docker中的/usr/local/xunsearch/data目录给映射出来,运行: ```bash docker run -d --name xunsearch -p 8383:8383 -p 8384:8384 \ -v /var/xunsearch/data:/usr/local/xunsearch/data hightman/xunsearch:latest ``` ## 配置文件(novel.ini) ``` project.name = novel project.default_charset = utf-8 server.index = 192.168.50.100:8383 server.search = 192.168.50.100:8384 ;配置信息 [id] type = id [title] type = title [content] type = body [author] type = string [category] type = numeric [favorites] type = numeric [update_time] type = numeric [create_time] type = numeric [hits_day] type = numeric [hits_week] type = numeric [hits_month] type = numeric [hits_time] type = numeric [word] type = numeric ``` ## 创建索引 ```php $start=$this->request->param('start', 0); //开始索引的作品ID $end=$this->request->param('end', 0); //结束索引的作品ID //创建XS对象 只要是对索引操作 都必须使用XS对象 $xs = new \org\XS('novel'); //获取索引对象(用来增删改的) $index = $xs->getIndex(); try{ $init=$this->request->param('init', 0); if($init) { //清空索引 $index->clean(); //完全清空索引数据如果当前数据库处于重建过程中将禁止清空 } while($init) { $books = Db::name('Novel')->where('id', 'gt', $start)->limit(1000)->select(); if(!$books) { break; } foreach($books as $book) { $start = $book['id']; $book['content'] = strip_tags($book['content']); pre('正在索引:' . $book['id'] . '《' . $book['title'] . '》'); $doc = new \org\XSDocument($book); //更新索引数据 $index->update($doc); if($end && $start>=$end) { break; } } if($end && $start>=$end) { break; } } if($init) { pre('同步索引'); //同步索引 使用flushIndex()方法 $index->flushIndex();//强制刷新服务端的当前库的索引缓存,上面说了不会立即生效需要等待若干秒,可以使用此方法来加快索引同步速度,也是异步的形式,只不过是尽可能快的立即同步过去 } } catch(\org\XSException $e) { pre($e->getMessage()); //echo $e->getTraceAsString(); exit('error'); } ``` ## 搜索 ```php $page = Request::param('page', 1); $keyword = Request::param('keyword', NULL); $order = ''; $map = []; if (isset($keyword) ) { $xs = new \org\XS('novel'); $search = $xs->getSearch(); //结果集 $docs = $search //设置是否开启模糊查询 ->setFuzzy(false) //设置是否开启同义词查询 ->setAutoSynonyms(true) //设置查询结果显示条数 ->setLimit($limit, ($page - 1) * $limit) //查询关键字 ->setQuery($keyword) ->search(); //高亮处理,因为$docs的结果集不让修改,所以自己建一个数组并组装需要的字段 $res = []; foreach ($docs as $k => $doc) { $res[$k] = $doc->getFields(); $res[$k]['id'] = $doc['id']; $res[$k]['pic'] = ''; $res[$k]['tag'] = ''; $res[$k]['serialize'] = 1; $res[$k]['up'] = 0; $res[$k]['down'] = 0; $res[$k]['recommend'] = 1; $res[$k]['hits'] = 1; $res[$k]['url'] = url('home/novel/index', ['id' => $doc['id']]); $res[$k]['title'] = $search->highlight($doc['title']); $res[$k]['content'] = $search->highlight($doc['content']); $res[$k] = $this->data_change($res[$k], 'novel'); } //获得本次查询的结果总数(这是个估值) $matched = $search->getLastCount(); //下面这段代码是为了在原系统的标签中使用。 $config = Container::get('config')->pull('paginate'); /** @var Paginator $class */ $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']); $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']); return $class::make($res, $limit, $page, $matched, false, $config); } ``` 最后修改:4年前 © 著作权归作者所有