آموزش اتصال الستیکسرچ به لاراول: جستجوی سریع در دیتابیسهای بزرگ
زمانی که پروژه شما مقیاس میگیرد و حجم دادهها بالا میرود، کوئریهای متداول SQL مثل WHERE name LIKE '%term%' به سرعت تبدیل به گلوگاه سیستم میشوند. مصرف بالای CPU، قفل شدن جدولها و زمان پاسخدهی طولانی، تجربه کاربری را به شدت افت میدهد.
برای حل این چالش و دسترسی به قابلیتهایی مثل Full-Text Search، تصحیح خودکار خطاهای تایپی و فیلترهای چندگانه روی میلیونها رکورد، ابزار استاندارد این حوزه Elasticsearch است.
۱. راهاندازی الستیکسرچ با داکر
سریعترین روش برای راهاندازی الستیکسرچ در محیط لوکال استفاده از Docker است:
docker run -d --name elasticsearch \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
elasticsearch:8.11.0
بررسی صحت اجرا:
curl http://localhost:9200
۲. نصب پکیج کلاینت PHP
پکیج رسمی کلاینت Elasticsearch را با کامپوزر نصب کنید:
composer require elasticsearch/elasticsearch
سپس آدرس نود را در فایل .env قرار دهید:
ELASTICSEARCH_HOST=http://localhost:9200
۳. رجیستر کردن Service Provider
یک Service Provider اختصاصی ایجاد کنید تا کلاینت به صورت سینگلتون مدیریت شود:
php artisan make:provider ElasticsearchServiceProvider
تنظیمات را داخل app/Providers/ElasticsearchServiceProvider.php بنویسید:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Elastic\Elasticsearch\ClientBuilder;
use Elastic\Elasticsearch\Client;
class ElasticsearchServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Client::class, function () {
return ClientBuilder::create()
->setHosts([env('ELASTICSEARCH_HOST', 'http://localhost:9200')])
->build();
});
}
}
۴. ایندکس کردن دادهها با متد Chunk
برای جلوگیری از سرریز حافظه (Memory Exhaust) در دادههای پرتعداد، هرگز از Model::all() استفاده نکنید؛ بلکه دادهها را قطعهقطعه (Chunk) بفرستید:
Product::chunk(200, function ($products) use ($elasticsearch) {
foreach ($products as $product) {
$elasticsearch->index([
'index' => 'products',
'id' => (string) $product->id,
'body' => [
'name' => $product->name,
'description' => $product->description,
'price' => (float) $product->price,
'is_active' => (bool) $product->is_active,
],
]);
}
});
۵. جستجو و فیلترهای چندگانه
از کوئریهای ترکیبی bool برای ترکیب سرچ متنی با فیلترهای قطعی رنج قیمت یا وضعیت استفاده کنید:
$results = $elasticsearch->search([
'index' => 'products',
'body' => [
'query' => [
'bool' => [
'must' => [
[
'multi_match' => [
'query' => $searchTerm,
'fields' => ['name^3', 'description']
]
]
],
'filter' => [
['term' => ['is_active' => true]],
['range' => ['price' => ['gte' => 50, 'lte' => 500]]]
]
]
]
]
]);
چکلیست نهایی پیادهسازی
| مرحله | عملیات | مزیت اصلی |
|---|---|---|
| سرور | اجرای کانتینر داکر | ایزولهسازی سریع و آسان |
| کلاینت | سرویس پرووایدر سینگلتون | تزریق وابستگی تمیز |
| ایندکس | استریم چانک ۲۵۰تایی | عدم اشغال بیرویه RAM |
| کوئری | ترکیب Must و Filter | کش خودکار فیلترها و سرعت بالا |
| همگامسازی | Laravel Observer و Queue | بهروزرسانی بدون معطلی کاربر |