Driver Elasticsearch untuk Laravel Scout dengan kekuatan pertanyaan Elasticsearch.
Melalui komposer
composer require hilsonxhero/elasticvisionAnda akan memerlukan file konfigurasi untuk menentukan indeks Anda:
php artisan vendor:publish --tag=elasticvision-config Juga jangan lupa untuk mengikuti instruksi instalasi untuk Laravel Scout, dan dalam konfigurasi Laravel Scout Anda, atur driver ke elastic .
Anda dapat mendefinisikan pemetaan untuk indeks Anda dalam file konfigurasi elasticVision:
return [
' indexes ' => [
App Models Product ::class,
],
];php artisan scout:index productsphp artisan scout:import " AppModelsProduct " Dalam kasus terakhir Anda dapat mengimplementasikan antarmuka Explored dan menimpa pemetaan dengan fungsi mappableAs() .
Pada dasarnya ini berarti terserah Anda apakah Anda suka memiliki semuanya dalam model, atau secara terpisah dalam file konfigurasi.
Mengembalikan dokumen yang berisi istilah yang tepat di bidang yang disediakan.
Anda dapat menggunakan kueri istilah untuk menemukan dokumen berdasarkan nilai yang tepat seperti harga, ID produk, atau nama pengguna.
use App Models Post ;
$ posts = Post :: search ( ' lorem ' )
-> filter ( new Term ( ' published ' , true ))
-> get ();Mengembalikan dokumen yang berisi satu atau lebih istilah yang tepat di bidang yang disediakan.
Kueri istilahnya sama dengan istilah kueri, kecuali Anda dapat mencari beberapa nilai. Dokumen akan cocok jika berisi setidaknya satu istilah. Untuk mencari dokumen yang berisi lebih dari satu istilah yang cocok.
use App Models Post ;
$ posts = Post :: search ( ' lorem ' )
-> should ( new Terms ( ' tags ' , [ ' featured ' ], 2 ))
-> get (); field
Bidang (Opsional, Objek) yang ingin Anda cari.
boost
(Opsional, float) Jumlah titik mengambang yang digunakan untuk mengurangi atau meningkatkan skor relevansi kueri. Default ke 1.0.
Secara default, hasil pencarian Anda akan diurutkan berdasarkan skor mereka menurut Elasticsearch. Jika Anda ingin masuk dan memengaruhi penyortiran, Anda dapat melakukannya dengan menggunakan fungsi default orderBy() dari Laravel Scout.
use App Models Post ;
$ results = Post :: search ( ' Self-steering ' )
-> orderBy ( ' published_at ' , ' desc ' )
-> get ();Mengembalikan dokumen yang berisi persyaratan dalam kisaran yang disediakan.
use App Models User ;
$ results = User :: search ( ' fugiat ' )-> must ( new Range ( ' age ' ,[ ' gte ' => 18 , ' lte ' => 35 ]))-> get ();Mengembalikan dokumen yang berisi istilah yang sesuai dengan ekspresi reguler.
Ekspresi reguler adalah cara untuk mencocokkan pola dalam data menggunakan karakter placeholder, yang disebut operator. Untuk daftar operator yang didukung oleh kueri RegExp, lihat sintaks ekspresi reguler.
use App Models User ;
$ results = User :: search ( ' fugiat ' )-> must ( new RegExp ( ' username ' , ' k.*y ' , ' ALL ' , false ))-> get (); field
Bidang (Opsional, Objek) yang ingin Anda cari.
value
(Wajib, string) Ekspresi reguler untuk istilah yang ingin Anda temukan di <field> yang disediakan. Untuk daftar operator yang didukung, lihat sintaks ekspresi reguler.
flags
(Opsional, String) memungkinkan operator opsional untuk ekspresi reguler. Untuk nilai yang valid dan informasi lebih lanjut, lihat Sintaks Ekspresi Reguler.
case_insensitive
(Opsional, Boolean) memungkinkan pencocokan case tidak sensitif dari nilai ekspresi reguler dengan nilai bidang yang diindeks saat diatur ke true. Default false yang berarti sensitivitas kasus pencocokan tergantung pada pemetaan bidang yang mendasarinya.
boost
(Opsional, float) Jumlah titik mengambang yang digunakan untuk mengurangi atau meningkatkan skor relevansi kueri. Default ke 1.0.
Mengembalikan dokumen yang berisi istilah yang sesuai dengan pola wildcard.
Operator wildcard adalah placeholder yang cocok dengan satu atau lebih karakter. Misalnya, * operator wildcard cocok dengan nol atau lebih karakter. Anda dapat menggabungkan operator wildcard dengan karakter lain untuk membuat pola wildcard.
use App Models User ;
$ users = User :: search ()
-> should ( new Wildcard ( ' username ' , ' ki*y ' ))
-> get ();Mengembalikan dokumen yang cocok dengan teks, angka, tanggal atau nilai boolean yang disediakan. Teks yang disediakan dianalisis sebelum dicocokkan.
Kueri pertandingan adalah kueri standar untuk melakukan pencarian teks lengkap, termasuk opsi untuk pencocokan fuzzy.
use App Models Article ;
$ articles = Article :: search ()
-> must ( new Matching ( ' title ' , ' ipsum ' ))
-> get ();Mengembalikan dokumen yang berisi kata -kata dari teks yang disediakan, dalam urutan yang sama seperti yang disediakan. Istilah terakhir dari teks yang disediakan diperlakukan sebagai awalan, mencocokkan kata apa pun yang dimulai dengan istilah itu.
use App Models User ;
$ users = User :: search ()
-> should ( new MatchPhrasePrefix ( ' message ' , ' quick brown f ' ))
-> get (); Kueri match_phrase menganalisis teks dan membuat kueri phrase dari teks yang dianalisis. Misalnya:
use App Models User ;
$ users = User :: search ()
-> should ( new MatchPhrase ( ' message ' , ' this is a test ' ))
-> get ();Membungkus pertanyaan lain untuk mencari ladang bersarang.
Permintaan nested mencari objek lapangan bersarang seolah -olah mereka diindeks sebagai dokumen terpisah. Jika suatu objek cocok dengan pencarian, permintaan nested mengembalikan dokumen induk root.
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 );Kueri frasa cocok dengan istilah hingga slop yang dapat dikonfigurasi (yang default ke 0) dalam urutan apa pun. Istilah yang ditransfer memiliki slop 2.
Analisis dapat diatur untuk mengontrol penganalisa mana yang akan melakukan proses analisis pada teks. Itu default ke definisi pemetaan eksplisit bidang, atau penganalisa pencarian default, misalnya:
Sebagian besar konfigurasi yang akan Anda lakukan melalui pemetaan indeks Anda. Namun, jika misalnya Anda ingin mendefinisikan pengaturan Elasticsearch yang lebih canggih seperti analisis atau tokenizer yang perlu Anda lakukan menggunakan pengaturan indeks.
Ketahuilah bahwa setiap kali Anda mengubah pengaturan indeks, Anda perlu membuat ulang indeks.
Untuk mulai menggunakan pengaturan indeks, kami akan memperluas pada model POST dengan fungsi indexSettings untuk mengatur penganalisa.
<?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 ' ],
],
],
],
];
}
}Analisis teks ditetapkan sebagai bagian dari pengaturan indeks.
Contoh berikut menciptakan penganalisa sinonim, hasil akhirnya adalah ketika Anda mencari 'vue' Anda (juga) mendapatkan hasil untuk 'bereaksi'. Untuk memastikan sinonim cocok dengan semua kasus, filter lowercase juga dijalankan.
<?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 ();
}
}Agregasi adalah bagian dari permintaan pencarian Anda dan dapat meringkas data Anda. Anda dapat membaca lebih lanjut tentang agregasi di Elasticsearch dalam dokumentasi resmi. Pada saat ini tidak semua jenis agregasi dibangun, tetapi membuat yang hilang harus dilakukan (dan penambahan paket ini sangat disambut).
Menambahkan agregasi membuat kueri pencarian Anda lebih maju. Berikut adalah contoh dari aplikasi demo:
$ search = Cartographer :: search ();
$ search -> aggregation ( ' places ' , new TermsAggregation ( ' place ' ));
$ results = $ search -> raw ();
$ aggregations = $ results -> aggregations ();Ini akan mengembalikan serangkaian metrik pada berapa kali setiap tempat hadir dalam Indeks Elasticsearch.
Sangat mudah untuk membuat filter dan analisis sinonim, tetapi berhati -hatilah bahwa mereka 'mahal' untuk mencalonkan diri untuk Elasticsearch. Sebelum beralih ke sinonim, lihat apakah Anda dapat menggunakan wildcard atau pertanyaan fuzzy.
Dokumentasi Laravel Scout menyatakan bahwa "lebih maju" di mana "klausa saat ini tidak didukung". Hanya cek sederhana untuk ID yang dimungkinkan selain pencarian istilah fuzzy standar:
$ categories = Category :: search ( ' lorem ipsum ' )-> filter ( new MatchPhrase ( ' status ' , ' enable ' ))-> take ( 15 )-> get ();ElasticVision memperluas kemungkinan Anda menggunakan pembangun kueri untuk menulis kueri yang lebih kompleks.
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
);
}
}
Misalnya, untuk mendapatkan semua posting itu:
Anda dapat menjalankan permintaan pencarian ini:
$ 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 ;Terkadang Anda mungkin bertanya -tanya mengapa hasil tertentu dikembalikan atau tidak.
Berikut adalah contoh dari aplikasi demo ElasticVision, meskipun tidak dengan kueri yang kompleks:
class SearchController
{
public function __invoke ( SearchFormRequest $ request )
{
$ people = Cartographer :: search ( $ request -> get ( ' keywords ' ))-> get ();
return view ( ' search ' , [
' people ' => $ people ,
]);
}
} Untuk men -debug kueri pencarian ini, Anda dapat memanggil metode debug statis pada mesin elastis untuk Laravel Scout:
use Hilsonxhero ElasticVision Infrastructure Scout ElasticEngine ;
$ debug = ElasticEngine :: debug ();Kelas debug yang dikembalikan metode ini dapat memberi Anda kueri terakhir yang dieksekusi sebagai array atau sebagai JSON. Anda harus dapat menyalin-paste JSON sebagai kueri langsung ke Elasticsearch.
$ lastQueryAsArray = ElasticEngine :: debug ()-> array ();
$ lastQueryAsJson = ElasticEngine :: debug ()-> json ();Gunakan perintah impor Laravel Scout untuk membuat dan memperbarui indeks.
php artisan scout:import <model>
Misalnya, jika model Anda adalah "App Model Post" maka perintah akan seperti ini:
php artisan scout:import "AppModelsPost"
Jika Anda ingin membuat ulang indeks, pertama -tama pastikan itu dihapus dan kemudian buat. Tindak lanjuti dengan impor pramuka untuk mengisi ulang indeks juga.
Jika Anda menggunakan indeks alias, Anda harus menggunakan perintah ini alih -alih scout:import
php artisan elastic:update <index?>
Anda dapat menentukan indeks atau memilih untuk menghilangkannya dan perintah akan memperbarui semua indeks Anda. Misalnya, jika model Anda adalah "App Model Post" dan indeksnya adalah "Post":
php artisan elastic:update posts
php artisan scout:delete-index <model>
Gunakan perintah laravel scount delete-index untuk menghapus indeks.
Pastikan Anda telah mengonfigurasi indeks Anda terlebih dahulu di config/elasticvision.php dan jalankan perintah Scout.