سائق Elasticsearch لـ Laravel Scout مع قوة استفسارات Elasticsearch.
عبر الملحن
composer require hilsonxhero/elasticvisionستحتاج إلى ملف التكوين لتحديد فهارسك:
php artisan vendor:publish --tag=elasticvision-config لا تنس أيضًا اتباع تعليمات التثبيت الخاصة بـ Laravel Scout ، وفي تكوين Laravel Scout الخاص بك ، قم بتعيين برنامج التشغيل على elastic .
يمكنك إما تحديد الفهرس الخاص بك في ملف Config AlctingVision:
return [
' indexes ' => [
App Models Product ::class,
],
];php artisan scout:index productsphp artisan scout:import " AppModelsProduct " في الحالة الأخيرة ، يمكنك تنفيذ الواجهة Explored والكتابة فوق التعيين باستخدام وظيفة mappableAs() .
هذا يعني في الأساس أن الأمر متروك لك ما إذا كنت ترغب في الحصول على كل شيء معًا في النموذج ، أو بشكل منفصل في ملف التكوين.
إرجاع المستندات التي تحتوي على مصطلح دقيق في حقل متوفر.
يمكنك استخدام مصطلح الاستعلام للعثور على مستندات بناءً على قيمة دقيقة مثل السعر أو معرف المنتج أو اسم المستخدم.
use App Models Post ;
$ posts = Post :: search ( ' lorem ' )
-> filter ( new Term ( ' published ' , true ))
-> get ();إرجاع المستندات التي تحتوي على مصطلحات واحدة أو أكثر في حقل متوفر.
الاستعلام عن المصطلحات هو نفس الاستعلام المصطلح ، إلا أنه يمكنك البحث عن قيم متعددة. سوف يتطابق المستند إذا كان يحتوي على واحد على الأقل من الشروط. للبحث عن المستندات التي تحتوي على أكثر من مصطلح مطابق واحد.
use App Models Post ;
$ posts = Post :: search ( ' lorem ' )
-> should ( new Terms ( ' tags ' , [ ' featured ' ], 2 ))
-> get (); field
(اختياري ، كائن) الحقل الذي ترغب في البحث عنه.
boost
(اختياري ، تعويم) رقم النقطة العائمة المستخدمة لتقليل أو زيادة درجات صلة الاستعلام. الإعدادات الافتراضية إلى 1.0.
بشكل افتراضي ، سيتم فرز نتائج البحث عن طريق درجاتها وفقًا لـ Elasticsearch. إذا كنت ترغب في التدخل والتأثير على الفرز ، فيمكنك القيام بذلك باستخدام وظيفة orderBy() الافتراضية من Laravel Scout.
use App Models Post ;
$ results = Post :: search ( ' Self-steering ' )
-> orderBy ( ' published_at ' , ' desc ' )
-> get ();إرجاع المستندات التي تحتوي على مصطلحات ضمن نطاق متوفر.
use App Models User ;
$ results = User :: search ( ' fugiat ' )-> must ( new Range ( ' age ' ,[ ' gte ' => 18 , ' lte ' => 35 ]))-> get ();إرجاع المستندات التي تحتوي على مصطلحات تتطابق مع تعبير منتظم.
التعبير العادي هو وسيلة لمطابقة الأنماط في البيانات باستخدام أحرف العلامات المتصلة ، تسمى المشغلين. للحصول على قائمة بالمشغلين المدعومة من استعلام RegexP ، راجع بناء جملة التعبير العادي.
use App Models User ;
$ results = User :: search ( ' fugiat ' )-> must ( new RegExp ( ' username ' , ' k.*y ' , ' ALL ' , false ))-> get (); field
(اختياري ، كائن) الحقل الذي ترغب في البحث عنه.
value
(مطلوب ، سلسلة) تعبير منتظم عن المصطلحات التي ترغب في العثور عليها في <field> المقدمة. للحصول على قائمة بالمشغلات المدعومة ، راجع بناء جملة التعبير العادي.
flags
(اختياري ، السلسلة) يتيح المشغلين الاختياريين للتعبير العادي. للحصول على قيم صالحة ومزيد من المعلومات ، راجع بناء جملة التعبير العادي.
case_insensitive
(اختياري ، منطقي) يسمح بالمطابقة غير الحساسة للعلاج لقيمة التعبير العادية مع قيم الحقل المفهرسة عند ضبطها على TRUE. الافتراضي هو خطأ مما يعني أن حساسية حالة المطابقة تعتمد على تعيين الحقل الأساسي.
boost
(اختياري ، تعويم) رقم النقطة العائمة المستخدمة لتقليل أو زيادة درجات صلة الاستعلام. الإعدادات الافتراضية إلى 1.0.
إرجاع المستندات التي تحتوي على مصطلحات تطابق نمط بطاقة Wildcard.
مشغل Bildcard هو عنصر نائب يطابق حرفًا واحدًا أو أكثر. على سبيل المثال ، يطابق مشغل * Wildcard Zero أو أكثر. يمكنك الجمع بين مشغلي البطاقات البرية مع شخصيات أخرى لإنشاء نمط البدل.
use App Models User ;
$ users = User :: search ()
-> should ( new Wildcard ( ' username ' , ' ki*y ' ))
-> get ();إرجاع المستندات التي تتطابق مع نص أو رقم أو تاريخ أو قيمة منطقية. يتم تحليل النص المقدم قبل المطابقة.
استعلام المطابقة هو الاستعلام القياسي لأداء البحث عن النص الكامل ، بما في ذلك خيارات المطابقة الغامضة.
use App Models Article ;
$ articles = Article :: search ()
-> must ( new Matching ( ' title ' , ' ipsum ' ))
-> get ();إرجاع المستندات التي تحتوي على كلمات نص متوفر ، بنفس الترتيب كما هو منصوص عليه. يتم التعامل مع الفترة الأخيرة من النص المقدم كبادئة ، مطابقة لأي كلمات تبدأ بهذا المصطلح.
use App Models User ;
$ users = User :: search ()
-> should ( new MatchPhrasePrefix ( ' message ' , ' quick brown f ' ))
-> get (); يحلل استعلام match_phrase النص ويقوم بإنشاء استعلام phrase من النص الذي تم تحليله. على سبيل المثال:
use App Models User ;
$ users = User :: search ()
-> should ( new MatchPhrase ( ' message ' , ' this is a test ' ))
-> get ();يلف استعلامًا آخر للبحث في الحقول المتداخلة.
عمليات تفتيش الاستعلام nested الأشياء المتداخلة كما لو تم فهرستها كوثائق منفصلة. إذا كان كائن ما يطابق البحث ، فإن الاستعلام nested يعيد وثيقة جذر الوالدين.
use App Models Product ;
$ products = Product :: search ()
-> must ( new Nested ( ' category ' , new Term ( ' category.id ' , 2 )))
-> get (); use App Models Product ;
$ search = Product :: search ( " lorem " );
// $feature_ids = array([4 => [1,2], 5 => [1,2]])
foreach ( request ()-> feature_id as $ key => $ value ) {
$ query = new BoolQuery ();
$ query -> must ( new Term ( ' features.feature_id ' , $ key ));
$ query -> must ( new Terms ( ' features.feature_value_id ' , $ value ));
$ boolQuery -> add ( ' must ' , new Nested ( ' features ' , $ query ));
}
$ search -> newCompound ( $ boolQuery );
$ products = $ search -> paginate ( 15 );يطابق استعلام العبارة المصطلحات حتى الانحدار القابل للتكوين (والذي يتخلف عن 0) بأي ترتيب. المصطلحات المنقولة لها انخفاض 2.
يمكن تعيين المحلل للتحكم في المحلل الذي سيؤدي عملية التحليل على النص. إنه يتخلف عن تعريف الحقل التعريف الصريح ، أو محلل البحث الافتراضي ، على سبيل المثال:
معظم التكوين الذي ستفعله من خلال تعيين الفهرس الخاص بك. ومع ذلك ، على سبيل المثال ، إذا كنت ترغب في تحديد إعدادات Elasticsearch أكثر تقدمًا مثل المحللين أو الرمز المميزات التي تحتاجها للقيام بذلك باستخدام إعدادات الفهرس.
كن على دراية أنه في أي وقت تقوم فيه بتغيير إعدادات الفهرس ، تحتاج إلى إعادة إنشاء الفهرس.
للبدء في استخدام إعدادات الفهرس ، سنوسع على نموذج البريد مع وظيفة indexSettings لتعيين محلل.
<?php
namespace App Models ;
use Illuminate Database Eloquent Factories HasFactory ;
use Illuminate Database Eloquent Model ;
use Hilsonxhero ElasticVision Application Explored ;
use Hilsonxhero ElasticVision Application IndexSettings ;
use Laravel Scout Searchable ;
class Post extends Model implements Explored , IndexSettings
{
use HasFactory ;
use Searchable ;
protected $ fillable = [ ' title ' , ' published ' ];
public function mappableAs (): array
{
return [
' id ' => ' keyword ' ,
' title ' => ' text ' ,
' published ' => ' boolean ' ,
' created_at ' => ' date ' ,
];
}
public function indexSettings (): array
{
return [
' analysis ' => [
' analyzer ' => [
' standard_lowercase ' => [
' type ' => ' custom ' ,
' tokenizer ' => ' standard ' ,
' filter ' => [ ' lowercase ' ],
],
],
],
];
}
}يتم تعيين تحليل النص كجزء من إعدادات الفهرس.
المثال التالي ينشئ محلل مرادف ، والنتيجة النهائية هي أنه عندما تبحث عن "Vue" (أيضًا) تحصل على نتائج "React". للتأكد من أن المرادفات تتطابق مع جميع الحالات ، يتم تشغيل المرشح lowercase أيضًا.
<?php
namespace App Models ;
use Illuminate Database Eloquent Factories HasFactory ;
use Illuminate Database Eloquent Model ;
use Hilsonxhero ElasticVision Application Explored ;
use Hilsonxhero ElasticVision Application IndexSettings ;
use Hilsonxhero ElasticVision Domain Analysis Analysis ;
use Hilsonxhero ElasticVision Domain Analysis Analyzer StandardAnalyzer ;
use Hilsonxhero ElasticVision Domain Analysis Filter SynonymFilter ;
use Laravel Scout Searchable ;
class Post extends Model implements Explored , IndexSettings
{
use HasFactory ;
use Searchable ;
protected $ fillable = [ ' title ' , ' published ' ];
public function mappableAs (): array
{
return [
' id ' => ' keyword ' ,
' title ' => [
' type ' => ' text ' ,
' analyzer ' => ' frameworks ' ,
],
' published ' => ' boolean ' ,
' created_at ' => ' date ' ,
];
}
public function indexSettings (): array
{
$ synonymFilter = new SynonymFilter ();
$ synonymFilter -> setSynonyms ([ ' vue => react ' ]);
$ synonymAnalyzer = new StandardAnalyzer ( ' frameworks ' );
$ synonymAnalyzer -> setFilters ([ ' lowercase ' , $ synonymFilter ]);
return ( new Analysis ())
-> addAnalyzer ( $ synonymAnalyzer )
-> addFilter ( $ synonymFilter )
-> build ();
}
}التجميعات هي جزء من استعلام البحث الخاص بك ويمكن أن تلخص بياناتك. يمكنك قراءة المزيد حول التجميعات في Elasticsearch في الوثائق الرسمية. في هذه اللحظة ، لا يتم بناء جميع أنواع التجميع ، ولكن يجب أن يكون إنشاء الأنواع المفقودة قابلة للتنفيذ (وهذه الإضافات إلى الحزمة مرحب بها للغاية).
إضافة التجميعات تجعل استعلام البحث الخاص بك أكثر تقدمًا. فيما يلي مثال من التطبيق التجريبي:
$ search = Cartographer :: search ();
$ search -> aggregation ( ' places ' , new TermsAggregation ( ' place ' ));
$ results = $ search -> raw ();
$ aggregations = $ results -> aggregations ();سيؤدي ذلك إلى إرجاع مجموعة من المقاييس حول عدد المرات التي يوجد فيها كل مكان في فهرس Elasticsearch.
من السهل جدًا إنشاء مرشحات ومحللات مرادف ، ولكن كن على علم بأنها "مكلفة" للترشح لـ Elasticsearch. قبل الانتقال إلى المرادفات ، تعرف على ما إذا كان يمكنك استخدام أحرف البدل أو الاستعلامات الغامضة.
تنص توثيق Laravel Scout على أن "أكثر تقدمًا" حيث "لا يتم دعم الجمل حاليًا". لا يمكن سوى إجراء فحص بسيط لـ ID إلى جانب البحث القياسي في مصطلح Guzzy:
$ categories = Category :: search ( ' lorem ipsum ' )-> filter ( new MatchPhrase ( ' status ' , ' enable ' ))-> take ( 15 )-> get ();يوسع مراسلة إمكانياتك باستخدام بناة الاستعلام لكتابة استفسارات أكثر تعقيدًا.
class Product extends Model implements Explored
{
public function mappableAs (): array
{
return [
' id ' => ' keyword ' ,
' title_fa ' => [
' type ' => ' text ' ,
' analyzer ' => ' my_analyzer ' ,
],
' title_en ' => [
' type ' => ' text ' ,
],
' status ' => [
' type ' => ' text ' ,
],
' category ' => ' nested ' ,
' features ' => ' nested ' ,
' variants ' => ' nested ' ,
' has_stock ' => ' boolean ' ,
];
}
public function toSearchableArray (): array
{
return [
' id ' => $ this -> id ,
' title ' => $ this -> title ,
' status ' => $ this -> status ,
' category ' => $ this -> category ,
' features ' => $ this -> features ,
' variants ' => ProductVariantResource :: collection ( $ this -> variants )-> toArray ( true ),
' has_stock ' => $ this -> has_stock ,
];
}
public function indexSettings (): array
{
return [
" analysis " => [
" analyzer " => [
" my_analyzer " => [
" type " => " custom " ,
" tokenizer " => " standard " ,
" filter " => [ " lowercase " , " my_filter " ]
]
],
" filter " => [
" my_filter " => [
" type " => " ngram " ,
" min_gram " => 2 ,
]
]
],
" index " => [
" max_ngram_diff " => 13
]
];
}
/**
* Get the name of the index associated with the model.
*
* @return string
*/
public function searchableAs ()
{
return ' products ' ;
}
public function category ()
{
return $ this -> belongsTo ( Category ::class);
}
public function variants ()
{
return $ this -> hasMany ( ProductVariant ::class);
}
public function features ()
{
return $ this -> hasMany ( ProductFeature ::class);
}
/**
* check inventory of product variations
*
* @return IlluminateDatabaseEloquentCastsAttribute
*/
protected function hasStock (): Attribute
{
return Attribute :: make (
get: fn ( $ value ) => $ this -> variants ()-> sum ( ' stock ' ) > 0 ? true : false
);
}
}
على سبيل المثال ، للحصول على جميع المنشورات:
يمكنك تنفيذ استعلام البحث هذا:
$ boolQuery = new BoolQuery ();
$ search = Product :: search ( " ipsum " )
-> field ( ' title ' )
-> field ( ' description ' )
-> filter ( new MatchPhrase ( ' status ' , ' enable ' ))
-> must ( new Nested ( ' category ' , new MatchPhrase ( ' category.id ' , 2 )));
if ( request ()-> filled ( ' available_stock ' )) {
$ search -> filter ( new Term ( ' has_stock ' , true ));
}
// request feature_ids value
// $feature_ids = array([4 => [1,2], 5 => [1,2]])
if ( request ()-> filled ( ' feature_ids ' )) {
foreach ( request ()-> feature_ids as $ key => $ value ) {
$ query = new BoolQuery ();
$ query -> must ( new MatchPhrase ( ' features.feature_id ' , $ key ));
$ query -> must ( new Terms ( ' features.feature_value_id ' , $ value ));
$ boolQuery -> add ( ' must ' , new Nested ( ' features ' , $ query ));
}
}
if ( request ()-> filled ( ' max_price ' ) && request ()-> filled ( ' min_price ' )) {
$ boolQuery -> add ( ' must ' , new Nested ( ' variants ' , new Range (
' variants.selling_price ' ,
[ ' gte ' => request ()-> min_price ]
)));
$ boolQuery -> add ( ' must ' , new Nested ( ' variants ' , new Range (
' variants.selling_price ' ,
[ ' lte ' => request ()-> max_price ]
)));
$ boolQuery -> add ( ' must_not ' , new Nested ( ' variants ' , new Range (
' variants.selling_price ' ,
[ ' lt ' => request ()-> min_price ]
)));
$ boolQuery -> add ( ' must_not ' , new Nested ( ' variants ' , new Range (
' variants.selling_price ' ,
[ ' gt ' => request ()-> max_price ]
)));
}
$ search -> newCompound ( $ boolQuery );
$ products = $ search -> paginate ( 15 );
return $ products ;في بعض الأحيان قد تتساءل لماذا يتم إرجاع بعض النتائج أو لم يتم إرجاعها.
فيما يلي مثال من تطبيق Demo AlctionVision ، على الرغم من أنه ليس مع استعلام معقد:
class SearchController
{
public function __invoke ( SearchFormRequest $ request )
{
$ people = Cartographer :: search ( $ request -> get ( ' keywords ' ))-> get ();
return view ( ' search ' , [
' people ' => $ people ,
]);
}
} لتصحيح استعلام البحث هذا ، يمكنك استدعاء طريقة debug الثابت على المحرك المرن لـ Laravel Scout:
use Hilsonxhero ElasticVision Infrastructure Scout ElasticEngine ;
$ debug = ElasticEngine :: debug ();يمكن أن تمنحك فئة التصحيح التي يعيدها هذه الطريقة آخر استعلام تم تنفيذه كصفيف أو كـ JSON. يجب أن تكون قادرًا على نسخ ملصق JSON كاستعلام مباشر إلى Elasticsearch.
$ lastQueryAsArray = ElasticEngine :: debug ()-> array ();
$ lastQueryAsJson = ElasticEngine :: debug ()-> json ();استخدم الأمر Laravel Scout Import لإنشاء مؤشرات وتحديثها.
php artisan scout:import <model>
على سبيل المثال ، إذا كان النموذج الخاص بك هو "App Models Post" ، فسيكون الأمر هكذا:
php artisan scout:import "AppModelsPost"
إذا كنت ترغب في إعادة إنشاء فهرس ، فتأكد أولاً من حذفه ثم إنشاءه. متابعة مع استيراد الكشافة لإعادة ملء الفهرس كذلك.
إذا كنت تستخدم الفهارس المستعارة ، فيجب عليك استخدام هذا الأمر بدلاً من scout:import
php artisan elastic:update <index?>
يمكنك تحديد فهرس أو اختيار حذفه وسيقوم الأمر بتحديث جميع الفهارس. على سبيل المثال ، إذا كان النموذج الخاص بك هو "App Model Post" والفهرس هو "منشورات":
php artisan elastic:update posts
php artisan scout:delete-index <model>
استخدم الأمر Laravel Scount Delete-Index لحذف المؤشرات.
تأكد من تكوين فهارسك أولاً في config/elasticvision.php وقم بتشغيل أوامر Scout.