تخفیف ویژه

آموزش الاستیک سرچ در لاراول: پیاده سازی جستجوی سریع و پیشرفته با الستیک سرچ

‏  11 دقیقه
۱۰ خرداد ۱۳۹۹
آموزش الاستیک سرچ در لاراول: پیاده سازی جستجوی سریع و پیشرفته با الستیک سرچ

در برنامه‌های تحت وب و موبایل جستجو و سرچ یکی از بخش‌های مهم محسوب می‌شود که تاثیر زیادی در تجربه کاربری دارد. هر چقدر جستجوی پیشرفته و سریع‌‌تری در برنامه خود داشته باشید، تجربه کاربری بهتری ایجاد می‌کنید. الاستیک سرچ (Elastic Search)  یک دیتابیس NoSql بر اساس سند (Document) می‌باشد که به‌طور گسترده‌ای، به دلیل index گذاری‌های پیشرفته در پیاده سازی Search و جستجو مورد استفاده واقع می‌شود. در این مقاله به آموزش الاستیک سرچ در لاراول به ‌وسیله ابزار Laravel Scout پرداخته‌ایم. همچنین این مقاله شامل یک ویدیوی آموزش فارسی الاستیک سرچ است.

Searching

فهرست محتوای این مقاله

نمونه‌های استفاده از Elastic Search:

نمونه‌های زیادی برای استفاده از Elastic به عنوان ابزار پیاده سازی جستجو و آنالیز داده‌ها وجود دارد. یکی از معتبرترین سایت‌هایی که از Elastic Search استفاده می‌کند دیجی کالا است که از این قابلیت در پیاده سازی جستجوی خود و هم چنین برای نگهداری Log‌های کاربران در وب سایت خود استفاده می‌کند.

نکته: می‌توانیم تمام داده هایی که جمع آوری می‌کنیم و قصد داریم بر اساس آن‌ها استراتژی کسب و کار خود را تعیین کنیم، در الاستیک سرچ ذخیره سازی کنیم.

بیشتر بدانید : Elasticsearch چیست؟

Query Language:

استفاده از Query Language برای دریافت داده‌ها به شما کمک می‌کند انواع فیلتر‌ها را بر روی داده‌های ذخیره شده پیاده سازی کنید و در نهایت به نتیجه‌ی دلخواه خود برسید. همچنین امکان توسعه الاستیک سرچ بر روی سرور‌های متعدد و قابلیت کلاستر شدن این امکان را می‌دهد تا میلیاردها رکورد داده را در این دیتابیس به راحتی ذخیره‌سازی کنید.

ابزار‌های کمکی:

الاستیک سرچ با ابزارهایی مانند Kibana و Logstash می‌تواند یک مجموعه کامل از ذخیره‌سازی، تحلیل و نمایش داده‌ها را  فراهم کند. Kibana یک ابزار برای نمایش داده‌های موجود در الاستیک سرچ می‌باشد که با استفاده از ابزار‌های خود می‌تواند انواع داده‌ها را به صورت چارت و گزارش نمایش دهد. همچنین با استفاده Logstash می‌توانید داده‌ها را در منابع مختلفی قرار دهید یا در یک قالب خاصی ذخیره سازی کنید. مثلا شما به راحتی می‌توانید داده هایی از یک فایل CSV را توسط Logstash در الاستیک سرچ ذخیره‌سازی کنید.

کانفیگ Database:

ابتدا یک Database جدید، به طور مثال به نام elastic می‌سازیم. سپس به پوشه‌ی لاراول خود و فایل env. رفته و تنظیمات Database را مانند شکل زیر تغییر می‌دهیم.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=elastic
DB_USERNAME=root
DB_PASSWORD=

حال در دستورات خط فرمان یا cmd خود در پوشه‌‌ای که اپلیکیشن لاراول قرار دارد، دستور زیر را اجرا می‌کنیم.

$ php artisan migrate

با اجرای دستور بالا، به صورت پیش‌فرض سه جدول به‌نام‌های failed_jobs ,migrations ,users در Database ساخته می‌شود. ما در این آموزش قصد داریم Elastic Search را بر روی نام ۱۰۰۰۰ کاربر پیاده‌سازی کنیم. به همین منظور ابتدا وارد tinker می‌شویم

$ php artisan tinker

سپس ۱۰۰۰۰ کاربر random به‌شکل زیر می‌سازیم.

>>> factory(App\User::class,10000)->create()

آموزش نصب Laravel Scout:

ابزاری که برای کار در لاراول و پیاده‌سازی Search به شکل کاملا سریع به آن نیازمندیم Laravel Scout می‌باشد. همچنین Elastic Search را باید با همین Match ،Laravel Scout کنیم.

برای نصب Laravel Scout دستور زیر را اجرا می‌کنیم.

composer require laravel/scout

حال باید آن را به صورت زیر Publish کنیم تا کانفیگ‌های Laravel Scout برای ما کار کند.

$ php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

بعد از Publish کردن توسط دستور بالا، در پوشه کانفیگ، فایلی به‌نام scout.php قرار می‌گیرد که در ادامه به شرح تمام بخش‌های آن می‌پردازیم.

scout.php:

درایور (Driver): به‌صورت پیش‌فرض درایور algolia ,Laravel Scout است.

'driver' => env('SCOUT_DRIVER', 'algolia'),

حال می‌‌خواهیم به‌ جای Elastic از algolia استفاده کنیم. برای این کار باید فایل درایور آن را نصب کنیم. اما قبل از‌ آن به فایل env. می‌رویم و برای SCOUT_DRIVER یک مقدار به‌ نام elasticsearch تعریف می‌کنیم.

SCOUT_DRIVER=elasticsearch

Prefix: نامی است که بر روی تمام index‌ها به‌صورت پیش‌فرض اعمال می‌شود.

'prefix' => env('SCOUT_PREFIX', ''),

Queue: زمانی که ما Searchable را use می‌کنیم، وقتی داده‌ای در Database اصلی، Delete ,Update ,Create می‌شود همزمان توسط Laravel Scout در درایوری که در بالا وارد کردیم به‌ طور مثال Elastic, همگام‌سازی (Sync) می‌شود.

حال هما‌ن‌طور که در ابتدا گفتیم، ما ۱۰۰۰۰ کاربر داریم و Sync کردن کاری زمان‌بر می‌باشد، به همین علت از Queue‌ها استفاده می‌کنیم که سرعت کار ما را صد‌ها برابر بهتر می‌کند.

'queue' => env('SCOUT_QUEUE', false),

برای فعال شدن queue مقدار آن را از false به true تغییر می‌دهیم.

آموزش نصب الاستیک سرچ

Faster

برای نصب Elastic Search راه‌های بسیار زیادی وجود دارد. ما در این آموزش از طریق Docker به نصب آن می‌پردازیم.

برای این‌کار در پوشه‌ی لاراول از طریق خط فرمان یا cmd دستور زیر را وارد می‌کنیم. (این کار به‌علت حجم بالا‌ی Elastic کمی زمان می‌برد)

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.7.0

سپس توسط دستور زیر آن را run می‌کنیم.

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.7.0

نصب درایور Elasticsearch:

ما به‌طور پیش‌فرض در لاراول درایور Elastic را نداریم. برای نصب آن از دستور زیر استفاده می‌کنیم.

composer require babenkoivan/scout-elasticsearch-driver

حال به scout.php رفته و تغییرات زیر را اعمال می‌کنیم.

// config/scout.php
// Set your driver to elasticsearch
    'driver' => env('SCOUT_DRIVER', 'elasticsearch'),

...
    'elasticsearch' => [
        'index' => env('ELASTICSEARCH_INDEX', 'laravel'),
        'hosts' => [
            env('ELASTICSEARCH_HOST', 'https://localhost'),
        ],
    ],

ادامه:

پس از نصب درایور و کانفیگ آن توسط دستور زیر تمام داده‌های Database را به Elastic منتقل می‌کنیم.

$ php artisan scout:import "App\User"

تا قبل از این‌ که Elastic را نصب کنیم برای گرفتن داده‌‌ها به‌طور مثال در UsersController به صورت زیر عمل می‌کردیم.

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class UsersController extends Controller
{
    public function search(Request $request)
    {
        return User::get();
    }
}

حال پس از نصب Elastic به‌طور مثال اگر بخواهیم تنها کاربران مرد نمایش داده شوند، کافی است از دستور زیر استفاده کنیم و پس از آن در Keyword, url را GET کنیم. (search?keyword=mr)

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class UsersController extends Controller
{
    public function search(Request $request)
    {
        return User::search("$request->keyword")->get() ;
    }
}

کانفیگ‌ Laravel Scout

Laravel Scout به صورت پیش‌فرض با درایوری به‌نام algolia کار می‌کند.

اگر بخواهیم در Model‌ها قابلیت Searchable موجود در Laravel Scout فعال شود باید آن را به صورت زیر use کنیم.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;
}

پس از اضافه کردن Searchable، متد‌ها و تنظیماتی در اختیار ما قرار می‌گیرد که در ادامه به معرفی متدهای مهم آن می‌پردازیم.

نام index:

به‌طور مثال همان‌طور که در پایین می‌بینیم، تابعی به نام ()searchableAs در اختیار ما قرار می‌گیرد که می‌توانیم نام index را انتخاب کنیم. ( در Elastic و algolia داده‌ها index گذاری می‌شوند.)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;

    /**
     * Get the index name for the model.
     *
     * @return string
     */
    public function searchableAs()
    {
        return 'posts_index';
    }
}

سفارشی‌سازی جست‌و‌جو Data:

برای این‌کار ابتدا تابع ()toSearchableArray را فراخوانی می‌کنیم و دستورات سفارشی‌سازی را در ...Customize array // وارد می‌کنیم.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;

    /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $array = $this->toArray();

        // Customize array...

        return $array;
    }
}

Model id:

به‌طور پیش‌فرض Laravel Scout برای Unique بودن یک id دارد که id همان Primary Key مدل ما می‌باشد. برای تغییر آن از تابع ()getScoutKey به‌صورت زیر استفاده می‌کنیم.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class User extends Model
{
    use Searchable;

    /**
     * Get the value used to index the model.
     *
     * @return mixed
     */
    public function getScoutKey()
    {
        return $this->email;
    }

     /**
     * Get the key name used to index the model.
     *
     * @return mixed
     */
    public function getScoutKeyName()
    {
        return 'email';
    }
}

انتقال داده‌های Database به Elastic:

برای انتقال تمام داده‌های Database اصلی به Database‌های Elastic یا algolia می‌توانیم از دستور ساده‌ی زیر استفاده کنیم.

$ php artisan scout:import "App\Post"

هم‌چنین برای حذف ‌آن‌ها از Database‌های Elastic یا algolia از دستور زیر استفاده می‌کنیم.

$ php artisan scout:flush "App\Post"

برای ‌این‌ که تنها بخش خاصی از داده‌ها به Elastic منتقل شوند، از Query استفاده می‌کنیم.

// Adding via Eloquent query...
App\Order::where('price', '>', 100)->searchable();

// You may also add records via relationships...
$user->orders()->searchable();

// You may also add records via collections...
$orders->searchable();

بروزرسانی داده‌ها:

برای بروز‌رسانی داده‌ها منطقی مانند بالا یعنی، انتقال داده‌ها حاکم است که با کد زیر تمام داده‌ها بروزرسانی می‌شوند.

$order = App\Order::find(1);

// Update the order...

$order->save();

هم‌چنین با کد زیر یک یا چند Query قبل از بروزرسانی داده‌ها، بر روی آن‌ها اعمال می‌کنیم.

// Updating via Eloquent query...
App\Order::where('price', '>', 100)->searchable();

// You may also update via relationships...
$user->orders()->searchable();

// You may also update via collections...
$orders->searchable();

حذف داده‌ها:

برای حذف داده‌ها نیز منطقی مانند بالا حاکم است که با کد زیر تمام داده‌ها حذف می‌شوند.

$order = App\Order::find(1);

$order->delete();

هم‌چنین با کد زیر یک یا چند Query قبل از حذف داده‌ها، بر روی آن‌ها اعمال می‌کنیم.

// Removing via Eloquent query...
App\Order::where('price', '>', 100)->unsearchable();

// You may also remove via relationships...
$user->orders()->unsearchable();

// You may also remove via collections...
$orders->unsearchable();

متوقف شدن Sync کردن:

اگر بخواهیم یک سری تغییرات در Database اصلی انجام دهیم و نخواهیم که با Elastic, همگام‌سازی (Sync) شود از دستور زیر استفاده می‌کنیم.

App\Order::withoutSyncingToSearch(function () {
    // Perform model actions...
});

گذاشتن شرط برای Searchable بودن:

اگر بخواهیم یک Model تنها به‌طور مثال هنگامی که Publish است قابل Search باشد. در آن Model از تابع ()shouldBeSearchable به‌صورت زیر استفاده می‌کنیم.

public function shouldBeSearchable()
{
    return $this->isPublished();
}

 Search کردن:

حال که کانفیگ‌های مختلف را انجام دادیم می‌توانیم به شکل زیر، به جست‌وجو در داده‌ها به‌ کمک Laravel Scout و درایور Elastic بپردازیم.

$orders = App\Order::search('Star Trek')->get();

هم‌چنین امکان دارد Search ما به‌ طور مستقیم از  route یا Controller باشد که در این صورت داده‌ها به فرمت JSON تبدیل می‌شوند که برای  Search کردن در آن‌ها از کد زیر استفاده می‌کنیم.

use Illuminate\Http\Request;

Route::get('/search', function (Request $request) {
    return App\Order::search($request->search)->get();
});

هم‌چنین اگر می‌خواهید داده‌ها به‌صورت خام یا raw در بیایند، از دستور زیر استفاده می‌کنیم.

$orders = App\Order::search('Star Trek')->raw();

برای اعمال Query‌های پیشرفته‌تر به صورت زیر عمل می‌کنیم.

$orders = App\Order::search('Star Trek')
    ->within('tv_shows_popularity_desc')
    ->get();

within: با استفاده از within، Collection می‌توانیم یک مقدار به آن بدهیم که داده‌هایی که به ما بر‌می‌گرداند همه در ابتدا، انتها یا هر جای دیگری از متن خود این مقدار را شامل می‌شوند.

سفارشی‌سازی Search Engine:

برای Customize کردن Search Engine می‌توانیم از دستورات زیر استفاده کنیم.

use Algolia\AlgoliaSearch\SearchIndex;

App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {
    $options['body']['query']['bool']['filter']['geo_distance'] = [
        'distance' => '1000km',
        'location' => ['lat' => 36, 'lon' => 111],
    ];

    return $algolia->search($query, $options);
})->get();

هم‌چنین برای اضافه کردن یک Engine به Laravel Scout به‌صورت زیر عمل می‌کنیم.

use Laravel\Scout\Builder;

abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function mapIds($results);
abstract public function map(Builder $builder, $results, $model);
abstract public function getTotalCount($results);
abstract public function flush($model);

ویدیو آموزش الاستیک سرچ در لاراول:

جمع بندی:

در این مقاله به آموزش الاستیک سرچ در لاراول به‌وسیله ابزار Laravel Scout پرداختیم. هم‌چنین برای تفهیم هر‌چه بهتر آن، تمام مطالبی که در این مقاله نوشته شده است را می‌توانید به‌ صورت  جامع و کامل در ویدیو بالا مشاهده نمایید. لازم به ذکر است که این ویدیو، تنها بخش مختصری از محتوای دوره متخصص لاراول هست.

اگر به یادگیری بیشتر لاراول علاقه داری می‌توانی در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنی، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه‌ها به صورت کامل برنامه‌ نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.

 

 

 

چه امتیازی به این مقاله می دید؟
نویسنده کیوان علی محمدی
یادگیرنده ی همیشگی،برنامه نویس،نویسنده،عاشق خلق چیزهای عجیب،عاشق تحلیل داده ها، مسئول بخش فنی و هم بنیان گذار در سون لرن.
ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :

 

نظرات کاربران

محمد شبانی

این مقاله نیاز به اپدیت داره
تنظیمات و کانفیگ پکیجی که نصب میکنید تغییراتی داشته که طبق آموزش شما جلو برن با خطا مواجه میشن. بهتره کسی خواست استفاده کنه داکیومنت ها رو خودش نگاهی بندازه

فائقه نامور

سلام ممنون از توجه شما
موردی که اشاره فرمودید به تیم تولید محتوا انتقال داده می شود.

دانیال یوسفی فر

این آموزشی دیگه منقضی شده است. از سون لرن درخواست میکنم مقاله رو بروزرسانی کنه.

حبیبه شعبانی

سلام
من طبق اموزش شما پیش رفتم و به این مشکل خوردم که نمبتونم فیلد های دلخواه انتخاب کنم
یعنی مثلا بگم که فقط توی نام و نام خانوادگی سرچ کن
آیا راه حلی هست؟

مسعود

برای من صفحه خالی نمایش میده .
فقط اینو نمایش میده[ ]

مسعود

من “tamayo/laravel-scout-elastic”: “4.0.0”, نصب کردم اما میخوام خودscoutرو نصب کنم نمیزاره میگه داخل پکیج scoutوجود داره

علی مجیدی

سلام
به‌ترتيب باید عمل کنید یعنی حتما اول Scout را باید نصب کنید، سپس elastic در غیر این صورت به همچین مشکلی برمی‌خورید.

sepehr

سلام ممنون بابت آموزش شما
دیگه با این روش نیازی به CDC بوسیله apache kafka هم نیست

Vahid

سلام، دقیقا متوجه نشدم که چرا برای اینکه دیتامونو index کنیم رو elastic باید دستور php artisan scout:”App\Model” رو بزنیم هر بار، خب اگه یه دیتا اضافه بشه چیکار کنیم، من از این پکیج استفاده میکردم https://appdividend.com/2018/06/30/laravel-elasticsearch-tutorial-example/?bs-comment-added=1#comment-46416 که اینجا هم به بن بست تاکتیکی خوردم و نتونستم به ازای هر مدل اون عمل indexing رو انجام بدم، خب من اومدم یه index تعریف کردم و حالا انتظار دارم که به ازای هر مدلم یه type بره و زیر اون index ام بسازه، در حالیکه یکبار به ازای یک مدلم میسازه و دیگه برای بقیه مدل هام نمیسازه، اگه تجربه ایی در این زمینه دارید کمکم کنید..

علیرضا ساجدی

سلام
ممنون از اموزش خوبتون
الان من روی ویندوز کار میکنم و برنامشو داخل ویندوز نصب کردم اگه ببرم روی هاست چطوری باید ورژن لینوکس نصب کنم؟یا نیازی نیست؟
راه حل چیه؟

علی مجیدی

سلام
نصب روی ويندوز قطعا حجم خاصی از حافظه رو از شما می‌گیره. نصب با Docker راه خیلی بهتری می‌تونه باشه اگر هم می‌خواهید روی Linux نصب کنید به مراجعه کنید.

مریم دانشور

به نظر شما چیکار باید بکنم

کیوان علی محمدی

سلام. احتمال زیاد خود elastic رو به صورت درست راه اندازی نکردید

ارام

سلام
طبق آموزش همه چیز خوب پیش میره و نصب میشه و دیتا هم انتقال پیدا میکنه
ولی مشکل من اینه که نمیتونم چنتا مدل رو انتقال بدم تنها اولین مدلی که با بچ اینپورت انتقال میدم در ادامه آپدیت میشه و …

چطوری میشه کاری کرد که عمل انتقال در همه مدل ها صورت بگیره؟
از الاستیک ورژن 6.7 و اسکات ورژن 5.3 استفاده میکنم و و درایور الاستیک ورژن 4

ممنون

ارام

ممنون از شما حلش کردم
مشکل اینه که باید ایندکس جدید بسازم برای مدل جدید که هرچی گشتم با این پکیج پیدا نکردم چجوری امکان پذیره و ناچارن از پکیج دیگری استفاده میکنم الان.

اما یه سوال راه اندازی رابطه ها در الاستیک سرچ چجوری ؟
لطفا یه آموزش بذارید براش

کیوان علی محمدی

سلام دوست عزیز. اگر دیتا منتقل نمیشه حتما خطایی وجود داره که باید در لاگ های لاراول اونو بررسی کنید، دلیل دیگه ای هم میتونه این باشه که تنظیمات مدل های دیگه به درستی تنظیم نمیشه.

Seyedreza Hosseini

با سلام و احترم
من طبق آموزش پکیج درایور Elasticsearch در لاراول 5.7 نصب می کنم اما ارور میده آیا در این نسخه از لاراول نصب این پکیج لازم نیست؟
ارور [Can you install one of :laravel/scout [5.0.x-dev,v6.1.3
با تشکر

کیوان علی محمدی

شما قبلش باید laravel scout رو حتما نصب کرده باشید.

حسن امجد

بسیار مفید بود
خسته نباشید

کیوان علی محمدی

سلام و ممنون. با VLC پخش کنید.

ما در سون لرن با محدودسازی دسترسی آزاد به اینترنت مخالفیم     اطلاعات بیشتر