該套件為 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
方法。