yucadoo / elasticsearcher-fractal
将 Elasticsearcher 与 PHP League 的 Fractal 包结合,以实现更简单的文档管理。
Requires
- php: ~7.2
- league/fractal: ^0.19.2
- madewithlove/elasticsearcher: ^0.5.2
- psr/container: ^1.0
Requires (Dev)
- phpunit/phpunit: >=8.0
- squizlabs/php_codesniffer: ^3.0
This package is auto-updated.
Last update: 2024-08-29 05:19:08 UTC
README
将 Elasticsearcher 与 PHP League 的 Fractal 包 结合,以实现更简单的文档管理。
本包符合 PSR-1、PSR-2、PSR-4 和 PSR-11 标准。如果发现不符合标准,请通过 pull request 提交补丁。
安装
通过 Composer
$ composer require yucadoo/elasticsearcher-fractal
用法
本包提供了 YucaDoo\ElasticSearcher\Managers\DocumentManager
类,它可以替代原始的 ElasticSearcher\Managers\DocumentsManager
类。它实际上封装了原始管理器,以更可重用和面向对象的方式提供相同的功能。
原始文档管理器处理原始文档,即数组。您始终必须指定 Elasticsearch 索引名称和 id,以及文档。新的文档管理器能够接受任何类型的输入,例如数据库模型。Elasticsearch 索引名称和 id 由给定输入确定,而 PHP League 的 Fractal 包 用于将输入转换为文档。如果您喜欢下面的内容,那么这正是您要找的包!
<?php use App\Models\User; // Implementation of the functions createWrappedDocumentManager() and createNewDocumentManager() is discussed later. // $originalDocumentManager = createWrappedDocumentManager(); $newDocumentManager = createNewDocumentManager($frameworkContainer); $user = new User(['id' => 123, 'name' => 'Administrator']); // Move transformation to fractal transformer // $data = ['id' => $user->id, 'name' => $user->name]; // $originalDocumentManager->index('users', '_doc', $data); $newDocumentManager->create($user); //$originalDocumentManager->bulkIndex('users', '_doc', [$data, $data, $data]); $newDocumentManager->bulkCreate([$user, $user, $user]); //$originalDocumentManager->update('users', '_doc', 123, ['name' => 'Moderator']); $user->name = 'Moderator'; $newDocumentManager->update($user); //$originalDocumentManager->updateOrIndex('users', '_doc', 123, ['name' => 'Super User']); $user->name = 'Super User'; $newDocumentManager->updateOrCreate($user); //$originalDocumentManager->delete('users', '_doc', 123); $newDocumentManager->delete($user); //$originalDocumentManager->exists('users', '_doc', 123); $newDocumentManager->exists($user); //$originalDocumentManager->get('users', '_doc', 123); $newDocumentManager->get($user);
新的文档管理器需要一个适配器,该适配器扩展了 YucaDoo\ElasticSearcher\Managers\DocumentAdapter
接口。适配器用于获取 Elasticsearch 索引名称和 id。以下是 Eloquent 模型的示例实现。
<?php namespace App\ElasticSearcher; use YucaDoo\ElasticSearcher\Managers\DocumentAdapter; class EloquentDocumentAdapter implements DocumentAdapter { /** * Get Elasticsearch id for Eloquent model. * @param \Illuminate\Database\Eloquent\Model $item Eloquent model. * @return string|int Elasticsearch id. */ public function getId($item) { return $item->getKey(); } /** * Get index name for Eloquent model. * @param \Illuminate\Database\Eloquent\Model $item Eloquent model. * @return string Elasticsearch index name. */ function getIndexName($item): string { // Elasticsearch index has the same name as database table. return $item->getTable(); } }
然后实现 Elasticsearch 的转换器。下面是一个示例。
<?php namespace App\ElasticSearcher\Transformers; use App\Models\User; use League\Fractal\TransformerAbstract; class UserElasticsearchTransformer extends TransformerAbstract { /** * Transform user into Elasticsearch document. * * @param User $user User to be converted into Elasticsearch document. * @return array Generated Elasticsearch document. */ public function transform(User $user) { return [ 'id' => $user->id, 'name' => $user->name, ]; } }
现在是我们将事情整合在一起的时候了。为此,我们需要一个 PSR-11 兼容的容器,它存在于大多数现代 PHP 框架中。大多数容器在给定完整的类名时返回类的实例。
文档管理器需要容器来获取用于处理输入的转换器实例。当处理用户时,需要一个 UserElasticsearchTransformer 实例;当处理 Post 模型时,需要一个 PostElasticsearchTransformer 实例,依此类推。文档管理器不知道转换器的类名。容器应根据索引名称解析转换器。为此,可以使用 AliasContainer(版本 2.0 或更高版本)。
我还建议使用 SingletonContainer 来缓存解析的转换器。
首先添加包。
$ composer require mouf/alias-container yucadoo/singleton-container
然后使用 AliasContainer 组合新的文档管理器。
<?php use App\ElasticSearcher\EloquentDocumentAdapter; use App\ElasticSearcher\Transformers\PostElasticsearchTransformer; use App\ElasticSearcher\Transformers\UserElasticsearchTransformer; use ElasticSearcher\Environment; use ElasticSearcher\ElasticSearcher; use ElasticSearcher\Managers\DocumentsManager as WrappedDocumentManager; use League\Fractal\Manager as FractalManager; use Mouf\AliasContainer\AliasContainer; use Psr\Container\ContainerInterface; use YucaDoo\ElasticSearcher\Managers\DocumentManager; use YucaDoo\SingletonContainer\SingletonContainer; /** * Resolve old document manager. This function is shown for completeness. * @return WrappedDocumentManager Document manager handling raw documents. */ function createWrappedDocumentManager(): WrappedDocumentManager { $env = new Environment( ['hosts' => ['localhost:9200']] ); $searcher = new ElasticSearcher($env); return $searcher->documentsManager(); } /** * Resolve new document manager. * @param ContainerInterface $container Container providing transformer instances. * @return DocumentManager Document manager handling models instead of raw documents. */ function createNewDocumentManager(ContainerInterface $container): DocumentManager { // Wrap container with singleton container to cache resolved transformers. $singletonContainer = new SingletonContainer($container); // Map index names to transformers. $transformerRepository = new AliasContainer($singletonContainer, [ 'posts' => PostElasticsearchTransformer::class, 'users' => UserElasticsearchTransformer::class, ]); // Compose document manager. return new DocumentManager( createWrappedDocumentManager(), new FractalManager(), new EloquentDocumentAdapter(), $transformerRepository ); }
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG。
测试
$ composer test
贡献
请参阅CONTRIBUTING和CODE_OF_CONDUCT以获取详细信息。
安全
如果您发现任何与安全相关的问题,请通过电子邮件hrcajuka@gmail.com而不是使用问题跟踪器进行报告。
致谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。