แพ็คเกจนี้เพิ่มฟังก์ชันการค้นหา/การกรองให้กับโมเดล Eloquent ใน Laravel 4/5/6
คุณยังอาจพบว่าแพ็คเกจเหล่านั้นมีประโยชน์:
เพิ่มบรรทัดต่อไปนี้ในไฟล์ composer.json
ในโปรเจ็กต์ของคุณ:
"jedrzej/searchable": "0.0.17"
หรือรันสิ่งต่อไปนี้ใน commandline ในโฟลเดอร์รูทของโปรเจ็กต์ของคุณ:
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
) ของการสืบค้นทั้งหมดกับโมเดลที่ค้นหาได้ สามารถเปลี่ยนเป็นการแยกทาง ( OR
) ได้โดยการตั้งค่าของพารามิเตอร์แบบสอบถาม mode
เป็น or
หากมีการใช้งานพารามิเตอร์การสืบค้น mode
อยู่แล้ว ชื่อที่ส่งคืนโดยเมธอด getQueryMode
จะถูกนำมาใช้
SearchableTrait
รองรับตัวดำเนินการต่อไปนี้:
ตัวดำเนินการเปรียบเทียบอนุญาตให้กรองตามผลลัพธ์ของการเปรียบเทียบคุณลักษณะของโมเดลและค่าการสืบค้น ใช้สำหรับสตริง ตัวเลข และวันที่ มีรูปแบบดังต่อไปนี้:
(<operator>)<value>
ตัวดำเนินการเปรียบเทียบต่อไปนี้พร้อมใช้งาน:
gt
greater than
การเปรียบเทียบge
สำหรับการเปรียบเทียบ greater than or equal
less than
การเปรียบเทียบ lt
le
สำหรับการเปรียบเทียบ les than or equal
หากต้องการกรองโพสต์ตั้งแต่ปี 2015 และใหม่กว่า ควรใช้คำค้นหาต่อไปนี้:
?created_at=(ge)2015-01-01
ลักษณะที่ค้นหาได้ช่วยให้สามารถกรองตามค่าที่แน่นอนของแอตทริบิวต์หรือตามชุดของค่า ขึ้นอยู่กับประเภทของค่าที่ส่งเป็นพารามิเตอร์การสืบค้น หากค่ามีเครื่องหมายจุลภาค พารามิเตอร์จะถูกแบ่งด้วยเครื่องหมายจุลภาคและใช้เป็นอินพุตอาร์เรย์สำหรับการกรอง IN
มิฉะนั้นจะใช้การจับคู่แบบตรงทั้งหมด
เพื่อกรองโพสต์จากผู้ใช้ที่มี ID 42 ควรใช้แบบสอบถามต่อไปนี้:
?user_id=42
เพื่อกรองโพสต์จากฟอรั่มที่มีรหัส 7 หรือ 8 ควรใช้แบบสอบถามต่อไปนี้:
?forum_id=7,8
ตัวดำเนินการ Like อนุญาตให้กรองโดยใช้แบบสอบถาม LIKE
โอเปอเรเตอร์นี้จะถูกทริกเกอร์หากใช้โอเปอเรเตอร์การทำงานแบบตรงทั้งหมด แต่ค่ามีเครื่องหมาย %
เป็นอักขระตัวแรกหรือตัวสุดท้าย
เพื่อกรองโพสต์ที่ขึ้นต้นด้วย How
ควรใช้แบบสอบถามต่อไปนี้:
?title=How%
Notice:
อักขระเปอร์เซ็นต์ใช้เพื่อเข้ารหัสอักขระพิเศษใน URL ดังนั้นเมื่อส่งคำขอ ตรวจสอบให้แน่ใจว่าเครื่องมือที่คุณใช้ encode the % character as %25
อย่างถูกต้อง
ตัวดำเนินการ Null (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's whereHas()
จะถูกนำไปใช้ หากต้องการกรองตามความสัมพันธ์ ให้เพิ่มแอตทริบิวต์ความสัมพันธ์ลงในรายการฟิลด์ searchable
ในแบบฟอร์ม relation:attribute
ควรใช้สตริงเดียวกันในแบบสอบถามเพื่อกรองตามแอตทริบิวต์ของความสัมพันธ์นั้น เช่น:
// allow filtering on user's active field
protected $searchable = ['user:active'];
// filter only posts of active users
?user:active=1
นอกจากนี้ยังเป็นไปได้ที่จะปฏิเสธการค้นหาและกรองวัตถุที่ไม่มีความสัมพันธ์ที่ตรงกันโดยการใช้ Eloquent'swhereDoesntHave 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