در این آموزش قصد داریم نحوه استفاده از Elasticsearch در لاراول را به شما آموزش بدهیم.
دراین آموزش ما از Elasticquent که یکی از پکیج های composer است، استفاده می کنیم. این پکیج مخفف عبارت Elasticsearch for Eloquent Laravel Modelsمی باشد.
Elasticquent کار با Elasticsearch و مدل های Eloquent را آسان می کند و این کار را با نگاشت آنها با نوع های Elasticsearch انجام می دهد.
شما می توانید از تنظیمات پیش فرض استفاده کنید یا تعریف کنید که چگونه Elasticsearch باید مدل های Eloquent شما را به درستی شاخص گذاری و جستجو کند.
Elasticquent به شما اجازه می دهد که یک مدل Eloquent را بگیرید و به آسانی محتوای آن را در Elasticsearch شاخص گذاری و جستجو کنید.
1- نصب Elasticsearch روی مک
2- نصب لاراول و Elasticsearch env
3- ایجاد یک مدل Article به همراه Migration آن
4- ایجاد داده های آزمایشی
5- نصب Elasticquent داخل مدل Article
6- جستجو با استفاده از متدهای Eloquent لاراول
این مثال را با نصب Elasticsearch روی مک شروع می کنیم.
در صورتی که قبلاً Elasticsearch را روی مک نصب نکرده اید، این مرحله را مطالعه کنید در غیراینصورت می توانید از این مرحله عبور کرده و مرحله بعد را بخوانید.
ابتدا با استفاده از homebrew (نرم افزار مدیریت پکیج) Elasticsearch را نصب می کنیم.
brew install elasticsearch
سپس با دستور زیر service را اجرا می کنیم
brew services start elasticsearch
با دستور زیر لاراول 5.6 را نصب کنید.
laravel new elasticlaravel
سپس وارد پروژه شوید:
cd elasticlaravel
پروژه را با یک ویرایشگر متنی باز کنید
code .
فایل .env را باز کرده و قسمت تنظیمات پایگاه داده آن را ویرایش کنید.
کدهای زیر را به فایل composer.json اضافه کنید. در این فایل ما پکیج Elasticquent را نصب می کنیم.
"require": { "php": "^7.1.3", "fideloper/proxy": "^4.0", "laravel/framework": "5.6.*", "laravel/tinker": "^1.0", "elasticquent/elasticquent": "dev-master" },
سپس کدهای زیر را برای نصب پکیج elasticquent اجرا کنید.
composer update
بعد از اینکه دستور composer update را اجرا کردید، باید service provider آن را در فایل config > app.php ثبت کنید.
// config/app.php 'providers' => [ ... Elasticquent\ElasticquentServiceProvider::class, ],
همچنین یک facade برای کلاینت elasticsearch فراهم می کنیم (که با استفاده از تنظیمات ما متصل می شود) و کدهای زیر را در config > app.php وارد کنید.
// config/app.php 'aliases' => [ ... 'Es' => Elasticquent\ElasticquentElasticsearchFacade::class, ]
دستور زیر را برای انتشار فایل تنظیمات داخل دایرکتوری تنظیمات برای لاراول 5.6 ، اجرا کنید:
php artisan vendor:publish --provider="Elasticquent\ElasticquentServiceProvider"
حال به فایل تنظیمات در مسیر app > config > elasticquent.php بروید.
در اینجا ما می خواهیم یک اسم شاخص برای برنامه خود اضافه کنیم، پس اسم آن را از default به articles تغییر می دهیم.
<?php // elastiquent.php return array( /* |-------------------------------------------------------------------------- | Custom Elasticsearch Client Configuration |-------------------------------------------------------------------------- | | This array will be passed to the Elasticsearch client. | See configuration options here: | | http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/_configuration.html */ 'config' => [ 'hosts' => ['localhost:9200'], 'retries' => 1, ], /* |-------------------------------------------------------------------------- | Default Index Name |-------------------------------------------------------------------------- | | This is the index name that Elasticquent will use for all | Elasticquent models. */ 'default_index' => 'articles', );
ما می خواهیم مقالات را با استفاده از elasticsearch جستجو کنیم.
ابتدا با دستور زیر مدل به همراه migration آن را ایجاد می کنیم:
php artisan make:model Article -m
سپس در فایل <DATETIME>_create_articles_table.php یک Schema اضافه کنید:
// create_articles_table.php public function up() { Schema::create('articles', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('body'); $table->string('tags'); $table->timestamps(); }); }
سپس با دستور زیر جدول را migrate کنید:
php artisan migrate
با دستور زیر یک ArticleTableSeeder ایجاد کنید.
php artisan make:seeder ArticleTableSeeder
برای تولید داده های ساختگی، از کتابخانه Faker استفاده می کنیم.
البته قبل از آن باید یک فیلد protected $fillable را داخل فایل Article.php ایجاد کنید تا از بروز خطای mass assignment exception جلوگیری شود.
// Article.php class Article extends Model { protected $fillable = ['title', 'body', 'tags']; }
حال، کدهای زیر را داخل فایل ArticleTableSeeder.php ایجاد کنید.
<?php // ArticleTableSeeder.php use Illuminate\Database\Seeder; use App\Article; class ArticleTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $faker = Faker\Factory::create(); for($i=0; $i<50; $i++) { Article::create([ 'title' => $faker->sentence(3), 'body' => $faker->paragraph(6), 'tags' => join(',', $faker->words(4)) ]); } } }
کلاس ArticleTableSeeder را داخل فایل DatabaseSeeder.php اضافه کنید
<?php // DatabaseSeeder.php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(ArticleTableSeeder::class); } }
حالا seeder را اجرا کنید و داده های ساختگی تان را با استفاده از دستور زیر ایجاد کنید
php artisan db:seed
کدهای زیر را داخل فایل Article.php ایجاد کنید.
<?php // Article.php namespace App; use Elasticquent\ElasticquentTrait; use Illuminate\Database\Eloquent\Model; class Article extends Model { use ElasticquentTrait; protected $fillable = ['title', 'body', 'tags']; protected $mappingProperties = array( 'title' => [ 'type' => 'text', "analyzer" => "standard", ], 'body' => [ 'type' => 'text', "analyzer" => "standard", ], 'tags' => [ 'type' => 'text', "analyzer" => "standard", ], ); }
در کد بالا ما تنظیمات نگاشت مورد نظرمان را برای Elasticsearch اضافه کردیم. جدول پایگاه داده سه فیلد اصلی دارد که ما باید به type و analyzer یک مقدار نسبت بدهیم که در ایجا ما standard را به آن می دهیم. همان طور که به یاد دارید اسم index برابر article بود. آرایه mappingProperties فیلدهایی دارد که باید با نوع (type) های مناسب برای جستجو و گرفتن بهترین نتایج ایندکس گذاری شود.
هر نگاشت (mapping) یک type و analyzer دارد. type ها می توانند شامل انواع مختلف نوع داده ها مثل رشته(string)، اعداد(number) و تاریخ(date) باشد.
ما در اینجا از نوع داده text استفاده کردیم اما شما می توانید از نوع داده های دیگری هم استفاده کنید.
برای کسب اطلاعات بیشتر درباره نوع داده ها ، مستندات Elasticsearch را مطالعه کنید.
حالا باید پایگاه داده را ایندکس گذاری کنیم. داخل فایل web.php کدهای زیر را بنویسید.
دقت داشته باشید که من کدهای زیر را در فایل web.php نوشتم ، اما در برنامه های واقعی شما باید این کدها را در کنترلر یا هر بخش دیگری که مسئول بخش منطق برنامه است (به جز web.php) بنویسید.
برای شاخص گذاری تمام ورودی ها در یک مدل Eloquent از addAllToIndex استفاده کنید.
Article::addAllToIndex();
همچین می توانید یک مجموعه از مدل ها را شاخص گذاری کنید:
$articles = Article::where('id', '<', 200)->get(); $articles->addToIndex();
با کد زیر می توانید یک فیلد خاص را شاخص گذاری کنید:
$articles = Article::find($id); $articles->addToIndex();
می توانید یک مدل را شاخص گذاری مجدد کنید.
Article::reindex()
حالا ما کل مدل را شاخص گذاری می کنیم، پس ما می توانیم کدهای شاخص گذاری را داخل روت ریشه( که با ‘\’ در فایل web.php نمایش می دهیم)
<?php // web.php use App\Article; Route::get('/', function () { Article::createIndex($shards = null, $replicas = null); Article::putMapping($ignoreConflicts = true); Article::addAllToIndex(); return view('welcome'); });
در اینجا ما صفحه index را ایجاد می کنیم. اسم ایندکس قبلا در فایل config > elasticquent.php تعریف شده بود.
سپس نگاشت هایی که در مدل Article.php تعریف کردیم را در آن قرار می دهیم و در انتها آن را با شاخص خود اضافه می کنیم.
آدرس http://localhost:8000 را در مرورگر وارد کنید.
با اینکار وارد صفحه welcome می شوید، اما داده هایمان شاخص گذاری می شود و برای بررسی صحت کارکرد برنامه، درخواست زیر را با استفاده از cURL ارسال می کنیم.
همچنین می توانیم از برنامه postman برای اینکار استفاده کنیم. اما من کد زیر را در ترمینال وارد میکنیم.
curl 'localhost:9200/articles/_mapping?pretty'
همچنین با دستور زیر می توانید یک جستجوی ساده روی آن انجام دهید:
curl 'localhost:9200/articles/articles/_search?q=title:Sed&pretty'
در اینجا ما کلمه sed را برای جستجو در قسمت عنوان مقالات ارسال می کنیم و برنامه به عنوان نتیجه جستجو رکوردهایی را که کلمه sed را دارند، بر می گرداند.
همچنین می توانیم نتایج رادر محیط ترمینال مانند زیر ببینیم:
ما تا اینجا از cURL برای جستجوی داده ها استفاده می کردیم. اما در اینجا می خواهیم از متدهای eloquent برای جستجوی داده ها بهره ببریم.
ابتدا یک روت در فایل web.php ایجاد کنید و کدهای زیر را در آن قرار دهید:
<?php // Article.php use App\Article; Route::get('/', function () { Article::createIndex($shards = null, $replicas = null); Article::putMapping($ignoreConflicts = true); Article::addAllToIndex(); return view('welcome'); }); Route::get('/search', function() { $articles = Article::searchByQuery(['match' => ['title' => 'Sed']]); return $articles; });
من کلمه sed را به صورت دستی به آن پاس دادم، اما در برنام های واقعی، عبارتی که میخواهیم جستجو کنیم را از یک فیلد input جستجو، دریافت می کنیم. آدرس http://localhost:8000/search را در مرورگر وارد کنید، همان طور که می بینید مرورگر کدهای json زیر را به ما بر می گرداند
البته شما ممکن است داده های متفاوت به شکل بالا دریافت کنید چون داده ها به صورت تصادفی تولید می شوند.
کلمه مورد نظرمان را به موتور جستجو پاس می دهیم و این موتور این عنوان را در پایگاه داده جستجو کرده و نتایجی مانند زیر را تولید می کند.
ما توانستیم با موفقیت داده ها را شاخص گذاری کرده و آنها را از موتور جستجوی Elasticsearch برگردانیم.
در این مثال ما در عنوان مقالات جستجو کردیم، اما شما می توانید برای محتوای پست ها و یا تگ های پست ها هم جستجو را انجام دهید.
$articles = Article::searchByQuery(['match' => ['body' => 'eligendi']]); return $articles;
همچنین می توانید برای تگ ها هم مانند بالا عمل جستجو را انجام دهید.
می توانیم تعداد نتایجی که با کلمه مورد جستجوی ما مطابقت داشت را بر گردانیم
$articles = Article::searchByQuery(['match' => ['title' => 'Heleium']]); return $articles->totalHits();
برای دسترسی به آرایه shards:
$articles->shards();
برای دسترسی به بیشترین امتیاز:
$articles->maxScore();
دسترسی به پروپرتی بولین time out:
$articles->timedOut();
دسترسی به پروپرتی took
$articles->took();
دسترسی به مجموعه (aggregation)های جستجو
$articles->getAggregations();
در صورتی که تعداد نتایج جستجوی شما زیاد باشد می توانید از تابع chunk() برای تقسیم آن به مجموعه های کوچکتر استفاده کنید.
$articles = Article::searchByQuery(['match' => ['title' => 'Similique']]); return $articles->chunk(2);
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.