ivone / n2search
搜索插件
This package's canonical repository appears to be gone and the package has been frozen as a result.
Requires
- php: >=7.0
- fukuball/jieba-php: ^0.33.0
- overtrue/pinyin: ^4.0
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2023-11-08 05:59:30 UTC
README

Laravel N₂Search
为Laravel设计的分词搜索工具
Github · Packagist · Report Bug
🌟 关于N2Search
Laravel为PHP提供了一个优雅使用的框架,无数的开发者为Laravel提供了非常多的工具组件。但是,在我使用的过程中,发现Laravel并没有一个比较好用且灵活调整的搜索工具,无论是官方提供的Scout还是基于Scout延伸出来的其他搜索工具,要么是过重(如:Scout+ElasticSearch方案)要么是不够便捷(如:Scout不支持许多Laravel ORM语法),致使在搜索中非常不方便。
所以,基于以上的问题,我用Jieba作为分词器,单独开发了一套存储在Redis中的分词索引,并且以Laravel ORM链式操作的形式,重新构建了一个Larave可用的便捷搜索工具,确保既能够有效分词,也能方便搜索调用。
🧩 特点
🌀 相比与Scout+数据库查询,效率要高
👨💻 可实现中文的拼音搜索
⛓ 支持类似Laravel Eloquent ORM链式操作,无违和感
📊 自动队列支持
🎰 支持多字段查询
🗃 搜索关键词提示
🕹 如何使用
🔧 版本要求
PHP
>= 7.0
Laravel
>= 8
确保安装Redis
🛠 安装
建议通过Composer来安装
composer require ivone/n2search
🎚️ 配置
composer安装好之后,需要在app/config/app.php
的providers
数组中增加N2SearchProvider,如下。
N2Search\N2SearchProvider::class,
然后执行php artisan vendor:publish
发布N2Search的配置文件,如果成功,则会在app/config/
目录中看到N2Search.php
文件。
return [ 'redis_host' => env('REDIS_HOST', '127.0.0.1'), // REDIS服务IP地址 'redis_password' => env('REDIS_PASSWORD', null), // REDIS密码 'redis_port' => env('REDIS_PORT', '6379'), // REDIS端口 'redis_db' => 9, // 给N2Search提供的可用REDIS库 'pinyin' => 1, // 1启动中文拼音检索 0关闭中文拼音检索 'dict' => 'big', // 分词词典,默认big,可选:small 'job_work' => 0, // 启用队列支持,可在导入时选用,默认0关闭,可选:1开启 'stop_words' => [] // 不分词词语配置 ];
📈 开始构建索引
你可以在你的Laravel项目中新建一个Command
,用命令行形式把你的数据表重新构建成搜索索引,便于你自定义你的索引关系。
$count = YourModel::count(); $bar = $this->output->createProgressBar($count); $n2 = new N2Search(); $logs = YourModel::get()->toArray(); foreach ($logs as $log) { $n2->load(YourModel::class, ['content'])->addOne($log['id']); $bar->advance(); } $bar->finish();
或者直接执行N2Search自带的Command
php artisan n2search:build {Your Model Class:App\\Model\\LogModel(etc)}
其中,以下两行代码是导入生成搜索分词索引的。
$n2 = new N2Search(); $n2->load(YourModel::class, ['content'])->addOne($log['id']);
即
load(Model的Builder构造器,以及对应Model中要构建索引的字段);
addOne
是指仅添加一条数据,需要额外增加ID主键参数。
addBatch
是可以一次性添加整个Model的所有数据,无需其他参数。
🔍 关键词查询
在完成第一步导入数据之后,就可以尝试从已构建的分词索引中查询数据了。
$n2 = new N2Search(); $n2->find(YourModel::class, '我')->columns(['name', 'degree'])->where(['user_id'=>1])->where(['relation_id'=>101])->page(1, 20)->order('id', 'desc')->fetchMany(); $n2->find(YourModel::class, '好的')->columns(['name', 'degree'])->where(['user_id'=>1])->order('id', 'desc')->fetchOne();
如果使用了fetchMany()
,后面增加了data()
方法来返回查询结果的数组,fetchOne()
不支持。
$n2 = new N2Search(); $n2->find(YourModel::class, '我')->columns(['name', 'degree'])->where(['user_id'=>1])->where(['relation_id'=>101])->page(1, 20)->order('id', 'desc')->fetchMany()->data();
其中
fetchMany()
表示一次性读取多条数据,如Laravel get()
fetchOne()
表示一次只读一条数据,如Laravel first()
查询主要参考了Laravel ORM的链式操作设计,可以多次绑定查询条件,并生成查询结果。N2Search的查询结果类型是Array。
🗑 删除/清理
$n2 = new N2Search(); $n2->clear()->flush(); $n2->clear()->remove($key1, $key2, $key3 ...);
或者直接执行N2Search自带的Command
全部清理。
php artisan n2search:clear
flush
方法对应 Redis 中的 flushdb
方法,清空在配置中 redis_db 中的所有内容
remove
是删除指定关键词,其中的$key参数可传任意长度
👏 完成
基础查询已经完成,你可以拿到N2Search提供的查询结果做你想做的逻辑处理了,更高级的功能和使用会在下文中逐一介绍。
💡 高级
🔤 拼音
参考开始构建索引
在项目publish之后,config目录下的N2Search.php
中,pinyin
一项改为1即可,0表示不转拼音。
🏳️🌈 多语言
开发中
🧳 队列
首先确保你的Laravel队列配置正确,如果是同步队列导入效率并不会有太大的变化,建议使用异步队列。
我本地用的是CentOS虚拟机,使用Supervisor做的队列守护进程,推荐一下
默认队列是n2_build
,如果你的机器资源足够,可以多开几个队列。
建议:
- 无需设置失败重试
- 尽量设置较高的内存分配(>=2048M)
- 2个以上的队列效果会比较明显
🗃 搜索关键词提示
开发中
🧮 权重计算
针对关键词的权重计算,不存在于fetchOne()
场景中,仅对fetchMany()
增加了对关键词在不同文档中的权重。
在fetchMany()
方法之后,以链式操作的形式,后面追加analysis()
方法,可返回关键词在文档中的权重,字段名为n2_weight
。
🧑🏻💻 联系我
你可以在github中给我提issue,或者邮件联系我:i@ivone.me
友情链接:方寸笔迹