眼看着Blog也写了不少了,经常要翻找一些之前写的blog来学(拷)习(备)下,但是发现通过 栏目和分页去寻找,还是太累了,决定写个检索
就决定是你了 -scout
scout 是laravel官方的一个检索拓展库,虽然现在里面的检索引擎(接口)只有 Algolia,但是也是可以自己拓展引擎的。
安装Scout
composer require laravel/scout
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
配置需要检索的模型
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
}
安装Algolia驱动
composer require algolia/algoliasearch-client-php:^2.2
配置Algolia
使用 Algolia 驱动的话,需要在配置文件 config/scout.php 中设置 Algolia 的 id 和 secret 信息(这些信息可以在注册登录 Algolia 之后在用户后台找到,分别对应 API Keys 下的 Application ID 和 Admin API Key)
目前Aligolia 免费版提供1w条数据和5w条操作可供使用,对于我的blog来说,应该是错错有余了,感恩Aligolia(为了表示感谢,再挂一次链接)
配置搜索数据(非必需)
因为发现我的blog内容过长,免费版的Algolia不支持我上传内容,我只能把 blog的 简介、栏目、tag一起传过去做检索了,不然光凭一个标题很难检索出我想要的内容。因为tag 、栏目我都是和blog做的多对多,无法通过默认模型监听更新到检索库。
这样的话我们就需要配置检索数据
namespace App; use Laravel\Scout\Searchable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Searchable; /** * 获取模型的索引数据数组 * * @return array */ public function toSearchableArray() { $array=array(); $array['title'] = $this->title;
$array['category'] = implode(" ",$this->category->pluck('title')->all());
$array['description'] = $this->description;
$array['tag'] = implode(" ",$this->tag->pluck('title')->all());
// 这里返回自定义数组... return $array; } }
批量导入
首次配置完成上面这些,如果数据库已有数据,这时候我们可以用指令进行批量导入
php artisan scout:import "App\Post"
ok,到这一步,如果不出意外的话,你的algolia 后台应该已经有了一批可检索的数据了。
非常智能,你每次上传、更新、删除 资源的时候,检索库也会自动更新。
but,到这一步,我遇到了一个很尴尬的问题,我更新blog的tag的时候,检索库没有进行同步更新。机制如我一猜就知道是因为 tag是关联表,当blog表更新完成,触发了提交检索数据以后,tag表才会进行更新,所以我虽然在blog模型的 toSearchableArray 方法中提交了 tag字段,但提交的时候却是空的。
好吧,刚好官方推荐我们用 队列来进行检索库数据提交,不出意外的话,队列也刚好能解决我的这个问题。
队列的配置
还好之前已经配置过了一个 基于datebase的队列了。
配置文件 config/scout.php
'queue' => env('SCOUT_QUEUE', true),
好了,到这一步我scout的配置已经完成了,接下来就是如何使用前台检索了。
前台检索
Blog::search($key)->paginate(10);
直接通过模型的search方法就可以进行关键词的检索,而且还支持 多词组合检索、近似词容错搜索。真的是很强大很方便了。
当然了,缺点也是有的,因为Algolia并没有大陆的服务器,所以检索速度并不是很快很稳定,而且每个月$29的基础班费用也不算很美好(你有钱任性当我没说)
根据我之前做过一次Algolia的经验,Algolia应该是可以设置 标题 、内容 等数据的一个检索优先级和排序规则,不过我暂时不需要这个,下次再去做
ps:使用scout 队列的时候,一定要配置队列的默认失败执行次数。scout自带的队列处理文件没有进行配置。
我就遇到这个坑了,没有配置最大失败执行次数,结果最大执行次数超过256(数据库执行次数字段为tinyint-3,队列执行记录插入数据库失败),导致队列堵塞, 队列默认执行日志没有执行记录。数据库 fail-jobs 也没用失败记录。还好最后在 laravel默认日志找到了相关记录,才排查掉问题。