Truy vấn tìm kiếm trong Laravel 8

Đối với một dự án mà tôi đang thực hiện, tôi cần xây dựng một công cụ tìm kiếm nhẹ, thực dụng. Trong bài đăng trên blog này, tôi muốn xem qua giải pháp của mình

Tìm kiếm các mô hình Eloquent

Hãy tưởng tượng bạn cần cung cấp tìm kiếm cho người dùng. Sử dụng Eloquent bạn có thể thực hiện tìm kiếm như thế này

User::query[]
   ->where['name', 'LIKE', "%{$searchTerm}%"] 
   ->orWhere['email', 'LIKE', "%{$searchTerm}%"] 
   ->get[];

Điều này sẽ trả về tất cả các bản ghi có tên hoặc email chứa chuỗi trong

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
1. Nếu bạn đang sử dụng MySQL, tìm kiếm này cũng sẽ được thực hiện theo cách không phân biệt chữ hoa chữ thường, đây có thể là điều bạn muốn

Sử dụng macro

Bây giờ, nếu bạn muốn thêm tìm kiếm, không chỉ mô hình

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
0 mà cho mọi mô hình, bạn có thể thêm macro vào trình tạo Truy vấn của Eloquent. Nếu bạn chưa bao giờ nghe nói về macro trong Laravel, hãy đọc bài đăng blog tuyệt vời này trên blog Tighten Co

Đây là cách macro của chúng tôi có thể trông như thế nào. Bạn có thể đặt nó theo phương pháp

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
1 của
use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
2 hoặc một nhà cung cấp dịch vụ của riêng bạn

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];

Bây giờ chúng ta có thể tìm kiếm mô hình của mình như thế này

User::query[]
   ->whereLike['name', $searchTerm]
   ->whereLike['email', $searchTerm]
   ->get[];

Cải thiện vĩ mô của chúng tôi

Vẫn còn chỗ để cải thiện. Tôi không thích thực tế là bây giờ chúng ta phải lặp lại lệnh gọi

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
3 đó cho mọi thuộc tính mà chúng ta muốn tìm kiếm. Hãy khắc phục điều đó. Đây là phiên bản cải tiến của macro của chúng tôi

Builder::macro['whereLike', function[$attributes, string $searchTerm] {
   foreach[array_wrap[$attributes] as $attribute] {
      $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
   }
   
   return $this;
}];

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
4 là một người trợ giúp nhỏ xinh của Laravel. Khi được cung cấp một mảng, nó chỉ trả về mảng đó. Khi được cung cấp một cái gì đó khác, nó sẽ bọc nó trong một mảng. Vì vậy, bạn biết kết quả sẽ luôn là một mảng

Macro ở trên có thể được sử dụng như thế này

// searching a single column
User::whereLike['name', $searchTerm]->get[];

// searching multiple columns in one go
User::whereLike[['name', 'email'], $searchTerm]->get[];

Sửa macro của chúng tôi

Macro của chúng tôi trông khá ổn, nhưng nó có một lỗi khó chịu

Xem xét truy vấn này

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
0

Nếu bạn nghĩ rằng điều này sẽ chỉ trả về những người dùng có vai trò

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
5 thì bạn đã nhầm. Bởi vì macro
use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
3 của chúng tôi chứa
use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
7, điều này sẽ trả về mỗi người dùng có vai trò
use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
5 và tất cả người dùng có tên hoặc email chứa
use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
9

Hãy khắc phục điều đó bằng cách gói các

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
7 của chúng ta vào một hàm. Điều này tương đương với việc đặt dấu ngoặc trong truy vấn tìm kiếm

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
7

Bây giờ, truy vấn trên sẽ trả về tất cả quản trị viên có tên hoặc email chứa

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
9

Thêm hỗ trợ cho các mối quan hệ

Hiện tại, chúng ta chỉ có thể tìm kiếm các thuộc tính của mô hình khi sử dụng phạm vi trên. Hãy thêm hỗ trợ để tìm kiếm các thuộc tính của các mối quan hệ của mô hình đó

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
9

Với macro đó có thể làm một cái gì đó như thế này

use Illuminate\Database\Eloquent\Builder;

// ...

Builder::macro['whereLike', function[string $attribute, string $searchTerm] {
   return $this->orWhere[$attribute, 'LIKE', "%{$searchTerm}%"];
}];
0

kết thúc

Macro trên thực hiện hoàn hảo những gì tôi cần trong dự án của mình. Nhưng bạn có thể đưa nó đi xa hơn. Đây là một biến thể được thực hiện bởi Sergio Bruder để phân chia các cụm từ tìm kiếm

Dựa trên macro tìm kiếm @freekmurze, phiên bản này chia nhỏ cụm từ tìm kiếm để bạn có thể tìm kiếm “Sergio Bruder” và tìm “Sergio Devojno Bruder”. Cụm từ tìm kiếm được AND'ed trên mỗi trường và OR'ed giữa các trường. vì vậy nó sẽ không tìm thấy tên “Sergio Else” và “bruder@email. com” thư. ảnh #laravel. Twitter. com/YxvmRRw16P

Làm cách nào để sử dụng tìm kiếm trong Laravel 8?

Thêm thuộc tính giá trị và đặt nó thành khóa tìm kiếm trong nội dung yêu cầu. .

Chủ Đề