第五章,我了解了怎么往数据库中存储数据,但是有很多数据需要本地或远程存储。本章,我们将了解 文件系统,内存中的存储,文件上传和操作,非关系数据存储,会话,缓存,日志记录,Cookie和全文本搜索。
本地和云文件管理
Laravel 提供了一系列文件操作工具,通过 Storage facade 和一些 助手函数。
Laravel 的文件系统可以连接 本地的文件系统, S3 ,rackspace 和 FTP。S3 和 Rackspace 文件驱动程序由 Flysystem 提供, 并且往 laravel 中添加其余的 Flysystem 支持的程序也很简单,如Dropbox或WebDAV。
配置文件
Laravel 文件管理的配置文件位于 config/filesystems.php 。 每个链接被叫做 “disk”,如下是一些开箱即用的 disk:
'disks' => ['local' => ['dirver' => 'local', // 本地文件系统'root' => storage_path('app'), // 存储位置在 storage/app],'public' => ['dirver' => 'local','root' => storage_path('app/public'),'url' => env('APP_URL') . '/storage','visibility' => 'public',],'s3' => ['dirver' => 's3', // 亚马逊 对象存储服务 云端存储'key' => env('AWS_ACCESS_KEY_ID'),'secret' => env('AWS_SECRET_ACCESS_KEY'),'region' => env('AWS_DEFAULT_REGION'),'bucket' => env('AWS_BUCKET'),'url' => env('AWS_URL'),]];
storage_path()助手函数,链接到 laravel 配置的 storage 目录,storage/., 所以,storage_path('public')将将返回storage/public。
public disk 也是使用本地文件系统,默认路径是 storage/app/public , 如果你想让该目录对公众开放,你需要创建一个软链接,映射该目录到 public 目录下, Artisan 命令可以帮助你:
php artisan storage:link
public/storage(对外可访问的位置) ==>storage/app/public(实际存放文件的位置)[http://lara.test/storage/9@2x.png](http://lara.test/storage/9@2x.png)实际访问的文件服务器地址是/path/to/myapp/storage/app/public/9@2x.png
使用 Storage Facade
config/filesystems.php 配置了默认的 disk ,当调用没有指定 disk 的 Storage facade 时, 将使用默认 disk。 指定 disk 的方法如下:
Storage::disk('s3')->get('file.jpg');
每个文件系统都提供了如下方法:
- get(‘file.jpg’)
Retrieves the file at file.jpg - put(‘file.jpg’, $contentsOrStream)
Puts the given file contents to file.jpg - putFile(‘myDir’, $file)
Puts the contents of a provided file (in the form of an instance of either
Illuminate\Http\File or Illuminate\Http\UploadedFile ) to the myDir direc‐
tory, but with Laravel managing the entire streaming process and naming the file - exists(‘file.jpg’)
Returns a Boolean indicating whether file.jpg exists - getVisibility(‘myPath’)
Gets the visibility for the given path (“public” or “private”) - setVisibility(‘myPath’)
Sets the visibility for the given path (“public” or “private”) - copy(‘file.jpg’, ‘newfile.jpg’)
Copies file.jpg to newfile.jpg - move(‘file.jpg’, ‘newfile.jpg’)
Moves file.jpg to newfile.jpg - prepend(‘my.log’, ‘log text’)
Adds content at the beginning of my.log - append(‘my.log’, ‘log text’)
Adds content to the end of my.log - delete(‘file.jpg’)
Deletes file.jpg - size(‘file.jpg’)
Returns the size in bytes of file.jpg - lastModified(‘file.jpg’)
Returns the Unix timestamp when file.jpg was last modified - files(‘myDir’)
Returns an array of filenames in the directory myDir - allFiles(‘myDir’)
Returns an array of filenames in the directory myDir and all subdirectories - directories(‘myDir’)
Returns an array of directory names in the directory myDir - allDirectories(‘myDir’)
Returns an array of directory names in the directory myDir and all subdirectories - makeDirectory(‘myDir’)
Creates a new directory - deleteDirectory(‘myDir’)
Deletes myDir
添加其他 Flysystem 提供商
如果你想添加一种其他的 Flysystem 提供商,你需要 ‘’继承’’ 本机的存储系统。在服务提供者的 root() 方法中——可以是 AppServiceProvider, 但是更合适的方式是为每一个新的储存系统创建一个新的 服务提供者。
// 某个服务提供者
public function boot()
{
Storage::extend('dropbox', function($app, $config){
$client = new DropboxClient($config['accessToken'], $config['clientIdentifier']);
return new Filesystem(new DropboxAdapter($client));
});
}
基本的文件上传和操作
Storage facade 的一个常规用处是接受用户上传的文件。以下是常见的流程
class DogsController
{
public function updatePicture(Request $request, Dog $dog){
Storage::put(
"dog/{$dog->id}",
file_get_contents($request->file('picture')->getRealPath())
);
}
}
我们 put() 一个叫 dog/id 的文件,并且从上传文件获取内容。每一个上传文件都属于 SplFileInfo 类,它提供了 一个getRealPath() 方法, 返回文件的地址 。所以,我们看可以我们得到了用户上传文件的最终上传路径,请使用 file_get_contents() 进行读取,并将其传递到 Storage::put()中。
这里,我们获取了文件变量, 在存储之前,我们可以对它做任何事——如果是图片的话,可以使用图像处理包,处理它,校验它,如果不符合我们的要求就拒绝它。
如果,我们想上传文件到 S3 , 并且 config/filesystems.php 已经配置好了, 只需要调用 Storage::disk('s3')->put() 即可,以下是稍微复杂的例子:
class DogsController
{
public function updatePicture(Resquest $request, Dog $dog){
$original = $request->file('picture');
// 修改 图片 大小 最大宽度为 150
$image = Image::make($original)->resize(150, null, function ($constraint){
$constraint->aspectRatio();
})->encode('jpg', 75);
Storage::put("dogs/thumbs/{$dog->id}", $image->getEncoded());
}
}
上例使用了 intervention/image 图片处理包。你也可以使用其他的。重点是,存储前你可以对图片做任何修改。
简单文件下载
就像上传一样简单,直接上代码:
public function downloadMyFile()
{
return Storage::download('my-file.pdf');
}
Sessions
session 在普通网页应用中,是存储不同页面状态的主要工具。Laravel 的 session 管理支持的驱动包括 files, cookies,database,Memcached or Redis,或者内存数组(在页面请求后过期,仅适用于测试)。
你可以在 config/session.php 中配置 session 。选择是否加密, 选择哪种驱动(默认 file), 指定其余信息,如 session 的长度或者要使用的文件或数据库表。session 文档
session 管理工具提供一些 api ,用于存储和获取数据:session()->put('user_id') 、session()->get('user_id')。 注意 请避免将任何内容 以 flash 作为 key 保存到 session,因为 Laravel 在内部将其用于 flash(仅可用于下一页请求)会话存储。
获取 Session
最常用的获取 session 的方法是:
session()->get('user_id');
你也可以使用 Request 对象的 session() 方法:
Route::get('dashboard', function(Request $request) {
$request->session()->get('user_id');
});
或者你可以注入一个 Illuminate\Session\Store 实例:
Route::get('dashboard', function (Illuminate\Session\Store $session) {
return $session->get('user_id');
});
最后,你还可以使用 session() 助手函数。不传参数获取一个 session 实例,可以跟 get() 、 put() 方法:
// Get
$value = session()->get('key');
$value = session('key');
$value = session('key', 'default'); // 设置默认值
// Put
session()->put('key', 'value');
session(['key', 'value']);
session 实例上可用的方法
最常用的是 get() 和 put(), 我们来看一下其他的。
session()->get($key, $fallbackValue)get()返回名字是$key的 session 值, 如果没有,则返回$fallbackValue(如果 $fallbackValue 没有设置,则返回null), $fallbackValue 可以是 字符串 或者 闭包, 如下:$points = session()->get('points'); $points = session()->get('points', 0); $points = session()->get('points', function(){ return (new PointGetterService)->getPoint(); });session()->put($key, $value)
以$key存储一个$value到session中session()->push($key, $value)
如果某个 session 的值是数组,你可以用push()往数组中追加值:session()->push('friends', ['Weimin', 'Yaqiong', 'Bengqun']); session()->push('friends', 'DuanMuDaShu');session()->has($key)
检查 是否存在以$key命名的 session:if(session()->has('points')){ // do something }你可以传入一个数组, 当 数组中的 key 对应的 session 都存在时,才返回 true.
ps: 如果一个 session 被设置了, 但是 值为null,则session()->has()返回false。session()->exists($key)
检查$key对应的 session, 是否被设置, 和has()不同的是,如果值被设置成null,也会返回true。session->all()all()返回所有session, 包括框架默认设置的。你可能会看到_token(CSRF tokens),_previous(上一个页面,back()重定向时候使用) , 和falsh(仅供 flash storage 使用)。session()->forget($key)和session()->flush()forget()移除一个之前设置的 session 值。flush()移除所有 session,包括框架自带的: ```php session()->put(‘a’, ‘awesome’); session()->put(‘b’, ‘be cool’);
session()->forget(‘a’); // 释放 a 的 session, b 依然被设置
session()->flush(); // session 为空
- `session()->pull($key, $fallbackValue)`<br />`pull()` 和 `get()` 一样, 唯一的不同是获取 session 后会删除这个值。
- `session()->regenerate()`<br />很少用,如果你要重新生成你的 `session` ID ,请使用。
<a name="993690f5"></a>
### 闪存会话存储 (Flash Session Storage)
一种常见的 session 存储应用模式是存储一个只在下一个页面加载时使用的值。 如 ,你可能存储一个 “数据提交成功” 的提示信息。 你可以在下一个页面加载时手动获取它然后擦除它,但是如果你在很多地方使用这种模式的话,很累吧。你可以把这些值存入 闪存会话存储 : 它被设置只存在到下一个页面请求。
laravel 提供了两个有用的方法:
- `session()->flash($key, $value)`<br />以 `$key` 存储一个 `$value` 到 session ,该值仅用于下一个页面请求。 和 `put()` 类似。
- `session()->reflash() and session()->keep($key)`<br />如果您需要上一页的 Flash 会话数据来处理另一个请求,则可以使用 `reflash()` 将所有内容 重新存储截至到下一个请求的,或者使用 `keep($key)` 仅为下一个请求重新存储一个值。 `keep()` 也可以接受要重新存储的值的 key 的数组。
<a name="a8d99b0b"></a>
## 缓存 Cache
缓存的结构类似于 session, 你提供一个 key ,larave 为你存储值。最大的不同是,缓存的存储是对整个项目而言的,`session`的存储是对每个用户而言的。这意味着,缓存经常用来存储来自数据库查询,API调用或其他查询缓慢的结果。
缓存的配置文件是 `config/cache.php` , 和 `session` 一样,你可以指定和配置任何一种缓存驱动,你也可以设置默认驱动。laravel 默认使用文件缓存,你也可以选择使用 `Memcached` `Redis` `APC` 或 数据库,设置你也可以写你自己的 缓存驱动。[cache文档](https://laravel.com/docs/master/cache)
laravel 5.8 之前你给缓存方法传递一个整数,代表缓存时间保存的 分钟数, 5.8+ 之后,代表缓存多少秒。
<a name="b06ce698"></a>
### 获取缓存
使用 `facade` :
```php
$users = Cache::get('users');
你也可以从容器中获取对象:
Route::get('users', function((Illuminate\Contracts\Cache\Repository $cache){
return $cache->get('users');
})
全局帮助函数:
// Get from cache
$users = cache('key', 'default value');
$users = cache()->get('key', 'default value');
// 存入缓存 并持续 $second 秒
$users = cache(['key' => 'value'], $second);
$users = cache()->put('key', 'value', $second);
缓存实例的方法
cache()->get($key, $fallbackValue)和cache()->pull($key, $fallbackValue)get()和pull()都是获取一个key 是$key缓存值,唯一区别pull()在获取缓存值后会释放该缓存。cache()->put($key, $value, $secondOrExpiration)
以$key存储一个$value到cache中, 并设置过期时间(秒数), 如果你想设置失效的 日期/时间 而不是秒数, 你也可以在第三个参数传入一个 Carbon 对象cache()->put('key', 'value', now()->addDay());cache()->add($key, $value)add()和put()很像,如果 $key 对应的值已经存在,它将不会设置。同时,这个方法返回一个 boolen 值 代表是否添加了缓存:$someDate = now(); cache()->add('someDate', $someDate); // retuen true $someOtherDate = now()->addHour(); cache()->add('someDate', $someOtherDate) // return falsecache()->forever($key, $value)
设置一个缓存,不会过期,除非被forget()。cache()->has($key)
返回是否有 名为 $key 的缓存cache()->remember($key, $seconds, $closure)和cache()->rememberForever($key, $closure)remember()提供了一种常见的工作流: 查询某个值是否 以$key为名存在于缓存中,如果存在返回它,如果不存在,先获取并以$key为名保存到缓存中,然后再返回它。remember第一个参数,是要查询的缓存键名,第二个参数,要缓存的时间,第三个参数,是一个闭包,定义了如果$key的键名不存在,怎么去查找值。rememberForever()类似,只是它不需要设置过期时间。eg:// 从缓存中获取以 'users' 为名字的缓存内容, // 如果未找到,则执行 Users::all() , 然后缓存到 'users' 中,持续 7200 秒,然后返回它 $users = cache()->remember('users', 7200, function(){ return Users::all(); });cache()->increment($key, $amount)和cache()->decrement($key, $amount)
自增,自减,起步值默认是 0 ,步伐宽度默认是 1。cache()->forget($key)和cache()->flush()forget($key)清除 $key 的缓存,flush()清除所有缓存。
Cookies
cookies 可以同时存在于 request 和 response 上,所以它和 session 与 cache 是不同的。
Laravel 中的 Cookie
Laravel 中 cookie 可以存在于三个地方,它可以依附于请求( request )上,这意味着,当用户访问页面时,会携带一个cookie 。你可以通过 Cookie facade 获取它,也可以从 request 对象上获取它。
它们可以跟着响应( response )被发送 , 这意味着,响应将指导用户的浏览器保存 cookie,以便于下一次访问。在返回响应之前你可以追加 cookie 到响应对象上。
最后,cookie 可以存在于队列中,当你使用 Cookie facade 设置 cookie 时,你已经把它放到一个名叫 “CookieJar” 的队列上了,这个队列将通过 AddQueuedCookiesToResponse 中间件往响应上添加和移除 cookie 。
cookie 工具
你可以使用三种工具获取或设置 cookie : Cookie facade ,cookie() 助手函数,request 和 response 对象。
Cookie facade
Cookie facade 是功能最齐全的选择。不仅允许你获取和设置 cookie, 还允许你把加到 response 上的 cookie 放到队列中,以下是它提供的方法:
Cookie::get($key)
获取一个名字为 $key 的 cookie ,它来自于 请求。Cookie::has($key)
检查请求中是否有名为$key的 cookie,返回 Boolean 值。Cookie::make(...params)
如果你想设置一个 cookie,但不想把它放到队列中,你可以使用Cookie::make()。这样使用,最大的可能性是,先设置一个 cookie ,然后手动把它绑定到响应对象上。
以下是make()的参数,按顺序:$namecookie 的名字$valuecookie 的内容$minutes指定 cookie 存在多少分钟$path$domain$secure表明 cookie 是否只应该发送到安全( HTTPS )的网站$httpOnly表明 cookie 是否只能通过 http 协议连接$raw表明 cookie 是否不使用 URL 编码$sameSite表明 cookie 是否对跨站请求可用,其值为lax,strict,null
Cookie::make()
返回一个Symfony\Component\HttpFoundation\Cookie实例Cookie::queue(Cookie || params)
如果你使用Cookie::make(), 你还需要把 cookie 绑定到响应上。Cookie::queue()和Cookie::make()有一样的语法,但是它通过中间件把自动创建 cookie 并绑定其到响应上放入队列。
你还可以把你创建好的 cookie 作为参数直接传递给Cookie::queue()。
最简单创建 cookie 并绑定它到响应:Cookie::queue('dismissed-popup', true, 15);
Cookie 的默认设置 Cookie facade 实例使用的 CookieJar 是从 session 配置中读取默认设置的。如果你更改了
config/session.php中的任何 session 和 cookie 配置,那么使用 Cookie facade 设置的使用了这些配置的所有 cookie 都会应用到。当队列中的 cookie 没有被设置时? Cookie 仅仅是作为响应的一部分返回。所以,如果你使用 Cookie facade 设置 cookie 放入队列,然后你的响应没有正确返回(例如,
exit()或者其他脚本中断),那么,你的 cookie 将不会被设置。
cookie() 助手函数
cookie() 函数不传递参数,返回一个 CookieJar 实例。然而,和 Cookie facade 相比,has() 和 get() 函数只有 Cookie Facade 上有,CookieJar 实例没有这两个函数。所以,某种程度上说, cookie() 助手函数有些鸡肋。
cookie() 助手函数最有用的是创建一个 cookie ,传递参数时,和 Cookie::make() 一样:
// 创建一个 cookie
$cookie = cookie('dismissed-popup', true, 15);
请求和响应中的 cookie
因为 cookie 作为请求的一部分被获取,作为响应的一部分被设置,这是 Illuminate 对象( 请求与响应)就是 cookie 生存的地方。Cookie facade 的 get() , has() , queue() 方法只是 请求与响应对象的操作 cookie 的代理。
所以,最简单的操作 cookie 的方法是使用 请求和响应对象。
从 Request 对象获取 cookie 。 你可以使用 Request 对象的 cookie() 方法获取 cookie:
Route::get('dashboard', function (Illuminate\Http\Request $request) {
$userDismissedPopup = $request->cookie('dismissed-popup', false);
});
参数 1是 cookie 的名字, 参数 2 是如果 cookie 不存在的默认值。
设置 cookie 到 Reponse 对象。无论 Response 对象是否准备好,你都可以使用 cookie() 方法(5.3 之前是 withCookie() )添加 cookie 到 Response 对象上:
Route::get('dashboard', function () {
$cookie = cookie('saw-dashboard', true);
return Response::view('dashboard')
->cookie($cookie);
});
如果你是一个 Laravel 新手,推荐使用 request 和 response 对象处理 cookie。虽然多做了一点工作,但是避免了之后的程序员,可能不理解 CookieJar 队列的问题。
日志
日志的最主要目的是增加 “可发现性”,即增强使你明白你的应用在任何时刻发生了什么的能力。
日志就是一些短信息,有时携带这某些数据,这些数据是对人可读且友好的。日志是在程序执行期间代码生成的,目的是方便你理解程序在执行时发生了什么。每个日志必须在特殊级别被捕获,可以从 emergency(非常严重)到 debug(几乎没什么有意义的发生)。
没有修改的情况下, Laravel 会把所有日志写在 storage/logs/laravel.log 文件里,每个日志看起来像这样:
[2020-08-08 10:37:00] local.ERROR: Something went wrong.
你可以看见 日期, 时间, 环境, 错误等级, 和错误信息都位于一行里。然而,Laravel 默认也会记录到任何没有捕获的异常到日志中,这种情况下,你将看到完整的堆栈信息。
什么时候需要为什么需要使用日志
日志最常见的应用场景是,对已经发生的事件做半一次性的记录, 这些记录你可能感兴趣,但是你绝对不会通过程序获取与访问。日志更多地是帮助了解应用程序发生了什么事情,而不是创建程序可以使用的结构化数据。
例如,你有一个记录用户登录或其他有意思的事情的代码,这就是一个登录数据库日志的应用场景。然而,你只是偶尔有兴趣,而且不确定是否需要关心,或者是否需要通过编程的方式获取这些信息,你可以抛出一个 debug 或者 info 等级的日志,然后忘记这回事。
日志也常用于,有什么地方出错时,你需要查看某个值,或者一天中的某个时间你不在跟前,你需要查看某个值。在代码中添加一条日志语句,把你需要的数据写进日志,是常见的解决方案。
写日志
最简单的方式是使用 Log facade,Laravel 提供了严格的日志等级, 遵循 RFC 5424 :
Log::emergency($msg);
Log::alert($msg);
Log::critical($msg);
Log::error($msg);
Log::warning($msg);
Log::notice($msg);
Log::info($msg);
Log::debug($msg);
你也可以传递第二个参数,是一个数组:
Log::error('some message',['user'=>$user])
不同的日志配置,附件信息可能会被以不同的方式捕获,以下是默认配置:
[2018-09-27 20:53:31] local.ERROR: Failed to upload user image. {
"user":"[object] (App\\User: {
\"id\":1,
\"name\":\"Matt\",
\"email\":\"matt@tighten.co\",
\"email_verified_at\":null,
\"api_token\":\"long-token-here\",
\"created_at\":\"2018-09-22 21:39:55\",
\"updated_at\":\"2018-09-22 21:40:08\"
})"
}
Log Channels
在 Laravel 5.6 即之后,我们配置和捕获日志的方式发生了相当大的变化,引入了多通道(channels) 和多驱动(dirvers)的思想。
你可以将你的日志配置成一种或者多种预定义的类型,只需要将类型涉及的各种配置信息传递给特定的驱动即可。
日志的类型称为 channel ,stack , single , daily , slack , stderr , syslog , 和 errorlog 都是开箱即用的。每个通道连接到单个 驱动, 可用的驱动有 single , daily , slack , syslog , errorlog , monolog , custom , 和 stack。
以下我们介绍几个,你还可以在 日志文档 查看详情 。
The single channel
single channel 会把每条日志写到一个文件里,这个文件路径需要设置在path 这里。 默认配置如下:
'single' => [
'dirver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug'
];
level 设置为 debug, 意味着只有 debug及 debug 以上的日志等级才会被记录。位置位于 storage/logs/laravel.log.
The daily channel
daily channel 会按照日期分割日志文件, 即每天创建一个新日志文件,记录当天日志。默认配置:
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 7
];
它类似于 single,但是我们现在可以设置日志保留多少天然后才可以被清理,并且我们将日期附加到我们指定的文件名之后。例如,以上配置将生成一个名为 storage/logs/laravel-{yyyy-mm-dd}.log 的文件。
The slack channel
发送日志到 slack 频道 (一个聊天工具)。
The stack channel
默认的日志 channel。laravel 5.7+ 默认配置如下:
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => 'false'
],
stack channel 允许你使用不止一种 channel, 你可以配置在 channel 数组中。所有,尽管它是 laravel 默认配置,5.8+ 之后 channel 数组设置的是 daily (如上),所以,其实它现在使用的还是 daily channel。
如果你想让 info 以上等级的日志放到 daily 文件, critical 等级以上的日志发送给 Slack。请使用如下配置:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'slack'],
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'info',
'days' => 14
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel log',
'emoji' => ':boom:',
'level' => 'critical'
],
]
在特定频道写日志
有时你想控制日志写到哪个频道,如下:
Log::channel('slack')->info('This message will go to slack');
更多的配置
使用 Laravel Scout 做全文搜索
Laravle Scout 是一个为你的 Eloquent Models 提供全文搜索的包。Scout 让搜索和索引你的 Eloquent models 的内容变得容易;它使用 Algolia 驱动,你也可以使用其他驱动,我们使用 Algolia 为例。
安装 Scout
首先, Larvael 5.3 + 执行如下命令:
composer require larvel/scout
ps: Laravle 5.5 版本之前需要添加 Laravel\Scout\ScoutServiceProvider::class 到 config/app.php 的服务提供者里。
其次,设置你的 Scout 配置,执行:
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
并且,黏贴你的 Algolia 证书 到 config/scout.php 文件。
最后,安装 Aligolia SDK:
composer require algolia/algoliiasearch-client-php
索引你的模型
在你的模型中,导入 Laravel\Scout\Serachable trait。 (我们使用 Review ,一个书籍评论表,举例)
你可以使用 toSearchableArray() 方法定义那些属性是可以被搜索的 (默认是映射 toArray()方法 ),你也可以使用 searchableAs() 方法定义模型索引的名字( 默认是 表名 )。
Scout 订阅了你标记的模型的 create / delete / update 事件。 当你创建,删除或者修改数据时,Scout 将会同步改变到 Algolia。它既能使这些改变同步,又能, 如果你使用了队列,队列也将更新。
搜索索引
Scout 同步很简单。例如,查找 Review 中含有 Llew 的:
Review::search('Llew')->get();
你可以使用 query,就像你使用正常的 Eloquent 一样:
// 分页
Review::search('Llew')->paginate(20);
Review::search('Llew')->where('account_id', 2)->get();
这些搜索 (searches) 返回什么呢?一个模型的 collection, 数据库的记录。 IDs 被存储在 Algolia,返回一个匹配 IDs 的列表;然后 Scout 从数据库拉取这些记录,作为 Eloquent 对象返回。
你不需要使用复杂的 SQL WHERE 语句,它为对比检查提供了一个简单的基本框架,就像你在代码中看到的一样简单。
队列和Scout
现在,每次修改数据库记录,你的应用都需要请求 Algolia 一次。这会拖慢应用程序的速度,所以使用 Scout 将这些 action 放入队列,是容易的。
在 config/scout.php 文件中, 设置 queue 为 true,这样这些修改建立索引将变成异步的。 现在,你的全文索引被操作为“最终一致性”;你的数据库将及时得到更新,你的搜索索引将会进入队列,按照队列工作进度,尽快更新。
不使用索引执行操作
如果你想执行系列操作,但是不想触发全文索引的响应。你可以把这些操作放到 withoutSyncingToSearch() 内:
Review::withoutSyncingToSearch(function(){
// 一些操作
factory(Review::class 10)->create();
})
索引前提条件
有时,你可能想当达到什么条件时,在索引记录。 在模型中使用 shouldBeSearchable():
public function shouldBeSearchable(){
return $this->isApproved();
}
通过代码手动触发索引
如果你想手动触发为你的模型建立全文索引,你可以通过代码,也可以通过命令行。
任何 Eloquent query 后调用 searchable(), query 的结果都会触发索引。
Review::all()->searchable();
关联方法上也可以使用:
$user->reviews()->searchable();
如果你想解除索引,也可以在任何 query 上使用 unsearchable() 方法:
Review::where('sucky', true)->unsearchable();
通过命令行手动触发索引
php artisan scout:import "App\Review"
这将触发 Review 模型所有记录索引。
