该包为 Laravel 4/5/6 中的 Eloquent 模型添加了搜索/过滤功能。
您还可以发现这些包很有用:
将以下行添加到项目中的composer.json
文件中:
"jedrzej/searchable": "0.0.17"
或在项目根文件夹中的命令行中运行以下命令:
composer require "jedrzej/searchable" "0.0.17"
为了使 Eloquent 模型可搜索,请将特征添加到模型中并定义模型可以过滤的字段列表。如果您想执行一些逻辑来定义可搜索字段列表,您可以定义 $searchable 属性或实现 getSearchableAttributes 方法。
use Jedrzej Searchable SearchableTrait ;
class Post extends Eloquent
{
use SearchableTrait ;
// either a property holding a list of searchable fields...
public $ searchable = [ ' title ' , ' forum_id ' , ' user_id ' , ' created_at ' ];
// ...or a method that returns a list of searchable fields
public function getSearchableAttributes ()
{
return [ ' title ' , ' forum_id ' , ' user_id ' , ' created_at ' ];
}
}
为了使所有字段都可搜索,请在可搜索字段列表中添加星号 *:
public $ searchable = [ ' * ' ];
还可以将模型的属性列入黑名单以防止其被过滤。
如果您想执行一些逻辑来定义可搜索字段列表,您可以定义 $notSearchable 属性或实现 getNotSearchableAttributes 方法。
use Jedrzej Searchable SearchableTrait ;
class Post extends Eloquent
{
use SearchableTrait ;
// either a property holding a list of not searchable fields...
public $ notSearchable = [ ' created_at ' ];
// ...or a method that returns a list of not searchable fields
public function getNotSearchableAttributes ()
{
return [ ' created_at ' ];
}
}
如果您定义两个列表(可搜索列和不可搜索列),则可搜索字段的结果集将包含除所有黑名单属性之外的所有白名单属性。
SearchableTrait
向模型添加了filtered()
范围 - 您可以向其传递一个作为过滤条件数组的查询:
// return all posts with forum_id equal to $forum_id
Post :: filtered ([ ' forum_id ' => $ forum_id ])-> get ();
// return all posts with with <operator> applied to forum_id
Post :: filtered ([ ' forum_id ' => <operator>])-> get ();
或者它将使用Request::all()
作为默认值:
// if you append ?forum_id=<operator> to the URL, you'll get all Posts with <operator> applied to forum_id
Post :: filtered ()-> get ();
默认查询模式是将所有查询的连接( AND
)应用于可搜索模型。通过将mode
查询参数的值设置为or
,可以将其更改为析取 ( OR
)。如果mode
查询参数已被使用,则将使用getQueryMode
方法返回的名称。
SearchableTrait
支持以下运算符:
比较运算符允许根据模型属性和查询值的比较结果进行过滤。它们适用于字符串、数字和日期。它们具有以下格式:
(<operator>)<value>
可以使用以下比较运算符:
gt
greater than
比较ge
用于greater than or equal
比较lt
用于less than
比较,例如le
用于les than or equal
比较为了过滤 2015 年及更新的帖子,应使用以下查询:
?created_at=(ge)2015-01-01
可搜索特征允许按属性的精确值或一组值进行过滤,具体取决于作为查询参数传递的值的类型。如果值包含逗号,则参数将按逗号分割并用作IN
过滤的数组输入,否则应用精确匹配。
为了过滤 ID 为 42 的用户的帖子,应使用以下查询:
?user_id=42
为了过滤 ID 为 7 或 8 的论坛中的帖子,应使用以下查询:
?forum_id=7,8
Like 运算符允许使用LIKE
查询进行过滤。如果使用完全匹配运算符,但值包含%
符号作为第一个或最后一个字符,则会触发此运算符。
为了过滤以How
开头的帖子,应使用以下查询:
?title=How%
Notice:
百分比字符用于对 URL 中的特殊字符进行编码,因此发送请求时请确保您使用的工具encode the % character as %25
空运算符(null)
允许过滤属性为空的模型。
为了过滤没有附件的帖子,应使用以下查询:
?attachment_id=(null)
通过在运算符前面添加!
可以获得否定的查询结果。 。
一些例子:
//filter posts from all forums except those with id 7 or 8
?forum_id=!7,8
//filter posts older than 2015
?created_at=!(ge)2015
//filter posts with attachment
?attachment_id=!(null)
可以对单个模型的属性应用多个约束。为了实现这一点,提供一组查询过滤器而不是单个过滤器:
// filter all posts from year 20** except 2013
?created_at[]=20%&created_at[]=!2013%
可以按模型关系的属性进行过滤 - 将应用 Eloquent 的whereHas()
。为了按关系进行过滤,请将关系属性添加到relation:attribute
形式的searchable
字段列表中。查询中应使用相同的字符串来按该关系的属性进行过滤,例如:
// allow filtering on user's active field
protected $searchable = ['user:active'];
// filter only posts of active users
?user:active=1
还可以通过应用 Eloquent 的whereDoesntHave()
来否定没有匹配关系的搜索和过滤对象。为此,请在关系名称前添加!
:
// allow filtering on comment's approved field
protected $searchable = ['comments:approved'];
// filter only posts that have approved comments
?comments:approved=1
// filter only posts that have not-approved comments
?comments:approved=1
// filter only posts that do not have approved comments
?!comments:approved=1
如果您想按嵌套关系进行过滤,只需提供嵌套关系的名称并将点替换为冒号即可。这是必要的,因为 PHP 会自动将 URL 中的点替换为下划线。
// filter only posts that have comments from active authors
?comments:author:active=1
可以使用您自己的逻辑处理选定的过滤器,例如,当过滤器名称与用于过滤的属性名称不匹配或需要执行某些自定义操作时。为了覆盖过滤器xyz
的逻辑,您需要在模型中定义一个名为processXyzFilter
的方法。如果过滤器已被处理并且默认逻辑不应再发生,则此方法应返回true
。
// use one filter to search in multiple columns
protected function processNameFilter ( Builder $ builder , Constraint $ constraint )
{
// this logic should happen for LIKE/EQUAL operators only
if ( $ constraint -> getOperator () === Constraint :: OPERATOR_LIKE || $ constraint -> getOperator () === Constraint :: OPERATOR_EQUAL ) {
$ builder -> where ( function ( $ query ) use ( $ constraint ) {
$ query -> where ( ' first_name ' , $ constraint -> getOperator (), $ constraint -> getValue ())
-> orWhere ( ' last_name ' , $ constraint -> getOperator (), $ constraint -> getValue ());
});
return true ;
}
// default logic should be executed otherwise
return false ;
}
要覆盖关系搜索的过滤器,请将过滤器名称中的冒号替换为下划线。如果您想覆盖user:active
的逻辑,您需要定义processUser_ActiveFilter
方法。