yucadoo/elasticsearcher-fractal

将 Elasticsearcher 与 PHP League 的 Fractal 包结合,以实现更简单的文档管理。

1.0.0 2020-07-31 21:21 UTC

This package is auto-updated.

Last update: 2024-08-29 05:19:08 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

Elasticsearcher 与 PHP League 的 Fractal 包 结合,以实现更简单的文档管理。

本包符合 PSR-1PSR-2PSR-4PSR-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

贡献

请参阅CONTRIBUTINGCODE_OF_CONDUCT以获取详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件hrcajuka@gmail.com而不是使用问题跟踪器进行报告。

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件