Laravel Scout的Elasticsearch驱动程序具有Elasticsearch查询的力量。
通过作曲家
composer require hilsonxhero/elasticvision您将需要配置文件来定义您的索引:
php artisan vendor:publish --tag=elasticvision-config Also do not forget to follow the installation instructions for Laravel Scout, and in your Laravel Scout config, set the driver to elastic .
您可以在ElasticVision配置文件中为您的索引定义映射:
return [
' indexes ' => [
App Models Product ::class,
],
];php artisan scout:index productsphp artisan scout:import " AppModelsProduct " In the last case you may implement the Explored interface and overwrite the mapping with the mappableAs() function.
从本质上讲,这意味着您是喜欢在模型中或在配置文件中分别将其全部合在一起取决于您。
返回在提供字段中包含确切术语的文档。
您可以使用术语查询根据价格,产品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的分数排序。 If you want to step in and influence the sorting you may do so using the default orderBy() function from 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
(Required, string) Regular expression for terms you wish to find in the provided <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 ();The match_phrase query analyzes the text and creates a phrase query out of the analyzed text.例如:
use App Models User ;
$ users = User :: search ()
-> should ( new MatchPhrase ( ' message ' , ' this is a test ' ))
-> get ();包装另一个查询以搜索嵌套字段。
The nested query searches nested field objects as if they were indexed as separate documents. If an object matches the search, the nested query returns the root parent document.
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,则需要使用索引设置来执行此操作。
请注意,每当您更改索引设置时,都需要重新创建索引。
To start using index settings, we will expand on the Post model with an indexSettings function to set an analyzer.
<?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”的结果。 To make sure the synonyms match all cases, the lowercase filter is run as well.
<?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 ,
]);
}
} To debug this search query you can call the static debug method on the Elastic Engine for 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"
如果要重新创建索引,请首先确保已删除该索引,然后创建它。跟进侦察兵进口,以重新填充索引。
If you are using Aliased Indexes, you should use this command instead of 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命令删除索引。
Be sure you have configured your indexes first in config/elasticvision.php and run the Scout commands.