Laravel Scout的Elasticsearch驅動程序具有Elasticsearch查詢的力量。
通過作曲家
composer require hilsonxhero/elasticvision您將需要配置文件來定義您的索引:
php artisan vendor:publish --tag=elasticvision-config同樣,也不要忘記遵循Laravel Scout的安裝說明,在Laravel Scout配置中,將驅動程序設置為elastic 。
您可以在ElasticVision配置文件中為您的索引定義映射:
return [
' indexes ' => [
App Models Product ::class,
],
];php artisan scout:index productsphp artisan scout:import " AppModelsProduct " 在最後一個情況下,您可以實現Explored接口並使用mappableAs()函數覆蓋映射。
從本質上講,這意味著您是喜歡在模型中或在配置文件中分別將其全部合在一起取決於您。
返回在提供字段中包含確切術語的文檔。
您可以使用術語查詢根據價格,產品ID或用戶名等精確值查找文檔。
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的分數排序。如果您想介入並影響分類,則可以使用Laravel Scout的默認orderBy()函數。
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時的情況不敏感。默認值為false,這意味著匹配的情況敏感性取決於基礎字段的映射。
boost
(可選,浮點)用於降低或增加查詢的相關得分的浮點數。默認為1.0。
返回包含與通配符模式相匹配的術語的文檔。
通配符操作員是與一個或多個角色相匹配的佔位符。例如, *通配符操作員匹配零或更多字符。您可以將通配符操作員與其他角色相結合以創建通配符模式。
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查詢返回root Parent文檔。
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設置,例如分析儀或Tokenizers,則需要使用索引設置來執行此操作。
請注意,每當您更改索引設置時,都需要重新創建索引。
為了開始使用索引設置,我們將使用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進行簡單檢查:
$ categories = Category :: search ( ' lorem ipsum ' )-> filter ( new MatchPhrase ( ' status ' , ' enable ' ))-> take ( 15 )-> get ();ElasticVision使用查詢構建器擴大您的可能性,以編寫更多複雜的查詢。
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 ;有時您可能想知道為什麼某些結果會或未返回。
這是Elasticvision演示應用程序中的一個示例,儘管沒有復雜的查詢:
class SearchController
{
public function __invoke ( SearchFormRequest $ request )
{
$ people = Cartographer :: search ( $ request -> get ( ' keywords ' ))-> get ();
return view ( ' search ' , [
' people ' => $ people ,
]);
}
}要調試此查詢,您可以在Laravel Scout的彈性引擎上調用靜態debug方法:
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中配置了索引並運行偵察命令。