PHP全文检索中间件,可索引上千万数据
前言
使用的是倒排索引结构,独立开发的中文分词,使用sqlite进行持久化存储,加上各种算法,实测可索引5000万数据。
这样一个PHP版的ES,在中小型项目中,就无需额外安装es软件,直接引入即可使用。
整个插件是独立运行的,不依赖任何其它插件,完全的接口化操作,使用方式也很简单:配置mapping、创建索引库 -> 导入数据 -> 开始搜索。下面简单介绍一下使用流程。
安装中间件
require 'yourdirname/wind-search-engine-professional/vendor/autoload.php';
配置mapping
// mapping字段配置
$field = [
[
'name' => 'id',//主键名称
'type' => 'primarykey' //数据类型为主键 int 必须
],
[
'name' => 'title', //字段名称
'index' => true, //代表需要索引
'type'=>'text',//数据类型:文本类型,会根据analyzer配置的方式进行分词
'analyzer' => 'segment', // 分词模式
],
[
'name' => 'tags',//字段名称
'index' => true,
'type'=>'keyword',//数据类型:关键词 不会分词
'analyzer' => 'segment', // 分词模式
],
[
'name'=>'descr', //不索引
],
[
'name'=>'link', //不索引
],
[
'name'=>'time', //不索引
],
];
导入数据
//导入数据
$Wind = new \WindSearch\Core\Wind($indexName);
// 开启分词
$Wind->loadAnalyzer(true);
//$result 数组 从数据库中查询的数据
foreach ($result as $v) {
$Wnd->indexer($v);
}
//每组$result数据导入后,进行批量保存,请合理设置分批查询的$result数据量
$Wind->batchWrite();
检索接口
match 单字段检索
match_phrase 短句检索
multi_match 多字段检索
match_prefix 前缀匹配
match_range 范围查询
match_terms 精确搜索
aggs_group 聚合搜索
geo_distance 地理空间搜索
match_bool 布尔搜索
DSL语法示例
多字段检索
//实例化引擎
$Wind = new \WindSearch\Core\Wind($indexName);
//开启分词功能
$Wind->loadAnalyzer();
// 开启同义词功能
$Wind->onNearSynonym();
//开启缓存功能
$Wind->onCache();
// 搜索多个字段
$query = [
'multi_match' => [
'field' => [
[
'name' => 'title',
'query' => $textTitle,
'analyzer' => 'segment', // 分词模式
'highlight' => [ // 结果高亮
'is_cut' => 'cut', // 是否将未匹配的地方截取掉
'fixed_length' => '', // 保留多少字符,若为空,则保持原长度
],
// 'weight' => 1, //字段权重
'minimum_should_match' => '75%', //控制精度 最少应该匹配几个,operator为空时,此项会起作用 值可以为整型或百分比
],
[
'name' => 'tags',
'query' => '蔬菜 水果',
'analyzer' => 'segment', /// 分词模式 complete/not,代表不分词 整体匹配; segment 中文分词;
'highlight' => [ //结果高亮
'is_cut' => 'not_cut', // 是否将未匹配的地方截取掉
'fixed_length' => '', // 保留多少字符,若为空,则保持原长度
],
'weight' => 2,
'minimum_should_match' => '15%',//控制精度 最少应该匹配几个,operator为空时,此项会起作用 值可以为整型或百分比
]
],
// 结果排序
'sort' => [
'time' => 'asc' //asc 按字段值正序 desc 按字段值倒序
],
'list_rows' => $listRows, // 每页多少条数据
'page' => $page, // 第几页
]
];
// 开始搜索
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...
bool搜索
// 布尔查询
$query = [
'match_bool' => [
'bool' => [
'must' => [
'match' => [
[
'title' => $text,
// 'level'=>'二级', //可以有多个条件
],
],
],
'should' => [
'match' => [
[
'area' => '中国',
],
[
'area' => '韩国',
],
],
'minimum_should_match' => 1, //最少应该同时满足几个
],
//必须不包含
'must_not' => [
'match' => [
['level' => '三级',],
['level' => '二级',],
],
],
//筛选过滤
'filter' => [
'range' => [//可多个过滤字段
'score' => [ //每个字段一个或两个条件 lt lte gt gte
'lt' => 1000,
'gt' => 9,
],
'time' => [
'lt' => 1710288994
],
],
],
],
'highlight' => [
'is_cut' => 'cut', // 是否将未匹配的地方截取掉
'fixed_length' => '', //保留多少字符,若为空,则保持原长度
],
// 结果排序
'sort' => [
'time' => 'desc' //asc 按字段值正序 desc 按字段值倒序
],
'_source'=>['id','title','descr'],//返回自定义字段,为空则全部返回
'list_rows' => $listRows, //每页多少条数据
'page' => $page, //第几页
],
];
// 搜索接口
$res = $Wind->search($query);
// $res 返回的最终结果,可直接渲染到前台页面
// ...
可以看到,整个过程跟使用es是差不多的,引入即可使用,插件内部自动完成所有功能(分词、索引、存储、搜索、排序等等),返回的结果可直接显示到前台页面,对于中小型网站的数据量,完全没有难度。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: