mypharmabr / plastic
plastic 是 Laravel 的 Elasticsearch ODM 和映射器。它通过提供映射、查询和存储 eloquent 模型的流畅语法,使开发者在使用 Elasticsearch 时体验更加愉悦。
Requires
- php: >=5.6.4
- elasticsearch/elasticsearch: ~2.2
- illuminate/console: 5.2.*|5.3.*|5.4.*|5.5.*
- illuminate/container: 5.2.*|5.3.*|5.4.*|5.5.*
- illuminate/contracts: 5.2.*|5.3.*|5.4.*|5.5.*
- illuminate/database: 5.2.*|5.3.*|5.4.*|5.5.*
- illuminate/pagination: 5.2.*|5.3.*|5.4.*|5.5.*
- illuminate/support: 5.2.*|5.3.*|5.4.*|5.5.*
- ongr/elasticsearch-dsl: ~2.0
Requires (Dev)
- mockery/mockery: ^0.9.4
- phpunit/php-code-coverage: ^2.1
- phpunit/phpunit: ~4.0
README
plastic 是 Laravel 的 Elasticsearch ODM 和映射器。它通过提供映射、查询和存储 eloquent 模型的流畅语法,使开发者在使用 Elasticsearch 时体验更加愉悦。
此包仍在积极开发中,可能有所变化。
安装 Plastic
composer require mypharmabr/plastic
然后我们需要将 plastic 服务提供者添加到 config/app.php 文件中的 providers 键下
MyPharmaBr\Plastic\PlasticServiceProvider::class
最后我们需要运行
php artisan vendor:publish
这将在 config/plastic.php 创建一个配置文件,并在 database/mappings 创建一个映射目录。
用法
定义可搜索模型
要开始,请通过添加 MyPharmaBr\Plastic\Searchable 特性来启用模型中的搜索功能
use MyPharmaBr\Plastic\Searchable; class Book extends Model { use Searchable; }
定义要存储的数据。
默认情况下,plastic 将使用 $model->toArray() 存储模型的所有可见属性。
此外,plastic 提供两种方式来手动指定哪些属性/关系应存储在 Elasticsearch 中。
1 - 为我们的模型提供可搜索属性
public $searchable = ['id', 'name', 'body', 'tags', 'images'];
2 - 提供一个 buildDocument 方法
public function buildDocument() { return [ 'id' => $this->id, 'tags' => $this->tags ]; }
自定义 elastic 类型名称
默认情况下,plastic 将使用模型表名作为模型类型。您可以通过向模型添加 $documentType 属性来自定义它。
public $documentType = 'custom_type';
自定义 elastic 索引名称
默认情况下,plastic 将使用配置文件中定义的索引。您可以通过将 $documentIndex 属性设置为模型来自定义模型数据将存储在哪个索引中。
public $documentIndex = 'custom_index';
存储模型内容
当您从我们的 SQL 数据库保存或删除模型时,plastic 会自动将模型数据与 elastic 同步,但是可以通过向模型添加 public $syncDocument = false 来禁用此功能。
需要注意的是,在以下场景中应手动更新文档
1 - 当您执行批量更新或删除时,没有触发 Eloquent 事件,因此文档数据不会同步。
2 - Plastic 还未监听相关模型的事件,因此当您更新相关模型的内容时,应考虑更新父文档。
保存文档
$book = Book::first()->document()->save();
部分更新文档
$book = Book::first()->document()->update();
删除文档
$book = Book::first()->document()->delete();
批量保存文档
Plastic::persist()->bulkSave(Tag::find(1)->books);
批量删除文档
$authors = Author::where('age','>',25)->get(); Plastic::persist()->bulkDelete($authors);
搜索模型内容
plastic 提供流畅的语法来查询 Elasticsearch,从而生成紧凑且易于阅读的代码。让我们深入了解
$result = Book::search()->match('title','pulp')->get(); // Returns a collection of Book Models $books = $result->hits(); // Returns the total number of matched documents $result->totalHits(); // Returns the highest query score $result->maxScore(); //Returns the time needed to execute the query $result->took();
要获取将要执行的原始 DSL 查询,您可以调用 toDSL()
$dsl = Book::search()->match('title','pulp')->toDSL();
分页
$books = Book::search() ->multiMatch(['title', 'description'], 'ham on rye', ['fuzziness' => 'AUTO']) ->sortBy('date') ->paginate();
您仍然可以使用 result 方法访问分页后的结果对象
$books->result();
布尔查询
User::search() ->must() ->term('name','kimchy') ->mustNot() ->range('age',['from'=>10,'to'=>20]); ->should() ->match('bio','developer') ->match('bio','elastic') ->filter() ->term('tag','tech') ->get();
嵌套查询
$contain = 'foo'; Post::search() ->multiMatch(['title', 'body'], $contain) ->nested('tags', function (SearchBuilder $builder) use ($contain) { $builder->match('tags.name', $contain); })->get();
请参阅这个 文档,了解 Plastic 中支持搜索查询及其应用方法。
动态更改索引
要为单个查询切换到不同的索引,只需使用 index 方法。
$result = Book::search()->index('special-books')->match('title','pulp')->get();
聚合
$result = User::search() ->match('bio', 'elastic') ->aggregate(function (AggregationBuilder $builder) { $builder->average('average_age', 'age'); })->get(); $aggregations = $result->aggregations();
请参阅这个 文档,了解 Plastic 中支持聚合及其应用方法。
建议
Plastic::suggest()->completion('tag_suggest', 'photo')->get();
建议查询构建器也可以直接从模型中访问
//this be handy if you have a custom index for your model Tag::suggest()->term('tag_term','admin')->get();
模型映射
映射是Elasticsearch的一个重要方面。您可以将它们与SQL数据库中的索引进行比较。对模型进行映射可以产生更好、更高效的搜索结果,并允许我们使用一些特殊的查询功能,如嵌套字段和建议。
生成模型映射
php artisan make:mapping "App\User"
新的映射将放置在您的 database/mappings 目录中。
映射结构
映射类包含一个名为 map 的单一方法。map方法用于映射给定的模型字段。
在 map 方法中,您可以使用 Plastic Map 构建器来表达性地创建字段映射。例如,让我们看看一个示例映射,它创建一个标签模型映射
use MyPharmaBr\Plastic\Map\Blueprint; use MyPharmaBr\Plastic\Mappings\Mapping; class AppTag extends Mapping { /** * Full name of the model that should be mapped * * @var string */ protected $model = App\Tag::class; /** * Run the mapping. * * @return void */ public function map() { Map::create($this->getModelType(), function (Blueprint $map) { $map->string('name')->store('true')->index('analyzed'); // instead of the fluent syntax we can use the second method argument to fill the attributes $map->completion('suggestion', ['analyzer' => 'simple', 'search_analyzer' => 'simple']); },$this->getModelIndex()); } }
要了解 Map 构建器上所有可用的方法,请参阅此文档。
运行映射
可以使用 Artisan 控制台命令运行创建的映射
php artisan mapping:run
更新映射
如果您的更新仅包括添加新的字段映射,您始终可以使用您的新字段更新我们的模型映射并运行
php artisan mapping:rerun
现有字段的映射无法更新或删除,因此您需要使用以下技术之一来更新现有字段。
1 - 创建新索引
您始终可以创建一个新的 Elasticsearch 索引并重新运行映射。在运行映射后,您可以使用 bulkSave 方法将您的 SQL 数据与 Elasticsearch 同步。
2 - 使用别名
建议创建具有别名的 Elasticsearch 索引,以简化在零停机时间内更新模型映射的过程。要了解更多信息,请参阅
https://elastic.ac.cn/blog/changing-mapping-with-zero-downtime
访问客户端
您可以通过以下方式访问 Elasticsearch 客户端来管理您的索引和别名
$client = Plastic::getClient(); //index delete $client->indices()->delete(['index'=> Plastic::getDefaultIndex()]); //index create $client->indices()->create(['index' => Plastic::getDefaultIndex()]);
有关官方 elastic 客户端的更多信息: https://github.com/elastic/elasticsearch-php
贡献
感谢您的贡献,贡献指南可以在这里找到。
许可证
Plastic 是开源软件,根据 MIT 许可证 许可。
待办事项
搜索查询构建器
- 实现提升查询
- 实现常量得分查询
- 实现 DisMaxQuery 查询
- 实现 MoreLikeThis 查询(使用原始 eloquent 模型)
- 实现 GeoShape 查询
聚合查询构建器
- 实现嵌套聚合
- 实现扩展统计聚合
- 实现 TopHits 聚合
映射
- 找到使用别名以零停机时间无缝更新字段映射的方法
通用
- 更好的查询构建器文档