umn/yii2-algolia

Yii2 的 Algolia 桥接器

安装: 6

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 5

类型:yii2-extension

2.0.0 2018-01-04 11:24 UTC

README

Latest Stable Version Latest Unstable Version Total Downloads License Build Status Code Coverage Scrutinizer Code Quality SensioLabsInsight

Yii2 Algolia 是一个为 Yii2 定制的 Algolia 桥接器。它使用官方的 Algolia 搜索 API 包 algoliasearch-client-php

目录

安装

使用 Composer 在项目的根目录中安装此包。

composer require leinonen/yii2-algolia

配置

将组件添加到应用程序配置中。同时启动该组件。

use leinonen\Yii2Algolia\AlgoliaComponent;
...
'bootstrap' => ['algolia'],
'components' => [
    'algolia' => [
        'class' => AlgoliaComponent::class,
        'applicationId' => 'test',
        'apiKey' => 'secret',
    ],
],

使用方法

使用此包的首选方式是通过依赖注入。只需注入 leinonen\Yii2Algolia\AlgoliaManager

它具有与官方 Algolia 客户端(AlgoliaSearch\Client)相同的方法。文档可在 此处 找到。管理器类将所有方法委托给原始客户端,并在其之上提供一些附加辅助工具。

use leinonen\Yii2Algolia\AlgoliaManager;

class MyController
{

    private $algoliaManager;

    public function __construct($id, $module, AlgoliaManager $algoliaManager, $config = [])
    {
        $this->algoliaManager = $algoliaManager;
        parent::__construct($id, $module, $config);
    }

    public function actionExample()
    {
        $index = $this->algoliaManager->initIndex("contacts");
        $results = $index->search("query string");
    }
}

您还可以像访问 Yii 组件一样访问管理器。

use Yii;

$index = Yii::$app->algolia->initIndex("contacts");

ActiveRecord 辅助工具

此包还提供处理 Yii 的 ActiveRecord 模型的辅助工具。

配置 ActiveRecord 类

要使用这些辅助工具,只需实现 leinonen\Yii2Algolia\SearchableInterfaceleinonen\Yii2Algolia\Searchable 特性提供了您所需的一切。您可以通过使用 fields()extraFields() 方法来控制要索引到 Algolia 的字段,就像您通常做的那样。您还可以覆盖 getAlgoliaRecord() 以实现更复杂的用例。

use leinonen\Yii2Algolia\ActiveRecord\Searchable;
use leinonen\Yii2Algolia\SearchableInterface;
use yii\db\ActiveRecord;

class Contact extends ActiveRecord implements SearchableInterface
{
    use Searchable;
}

默认情况下,辅助工具将使用类名作为索引的名称。您还可以指定要同步类到哪些索引。

class Contact extends ActiveRecord implements SearchableInterface
{
    use Searchable;

    /**
     * {@inheritdoc}
     */
    public function indices()
    {
        return ['first_index', 'second_index'];
    }
}

默认情况下,模型将使用 Yii 的 toArray() 方法在后台转换为数组。如果您想自定义它,可以覆盖 getAlgoliaRecord() 方法

class Contact extends ActiveRecord implements SearchableInterface
{
    use Searchable;
    
    /**
     * {@inheritdoc}
     */
    public function getAlgoliaRecord()
    {
        return array_merge($this->toArray(), ['someStaticValue' => "It's easy"]);
    }
}

为了提供 Algolia 的 ObjectID,该包使用来自 Searchable 模型的 getObjectID() 方法。默认情况下,辅助特将使用 ActiveRecord 的 getPrimaryKey() 方法。如果您想使用其他键,只需覆盖该方法(或者如果您不使用特性,则实现自己的方法)

class Contact extends ActiveRecord implements SearchableInterface
{
    use Searchable;
    
    /**
     * {@inheritdoc}
     */
    public function getObjectID()
    {
        return $this->getUuid();
    }
}

您还可以为纯 PHP 对象实现 leinonen\Yii2Algolia\SearchableInterface,然后使用 leinonen\Yii2Algolia\AlgoliaManager 来控制它们。请注意,所有辅助工具都只能在 ActiveRecord 类中使用。

索引

手动索引

您可以使用 leinonen\Yii2Algolia\Searchable 特性,通过在 ActiveRecord 模型上的 index() 实例方法上触发索引。

$contact = new Contact();
$contact->name = 'test';
$contact->index();

或者,如果您喜欢更服务化的架构,您可以使用 leinonen\Yii2Algolia\AlgoliaManager 上的方法

$contact = new Contact();
$contact->name = 'test';
$manager->pushToIndices($contact);

您还可以使用服务的 pushMultipleToIndices() 方法批量索引同一类的多个模型。

$contact1 = new Contact();
$contact1->name = 'test';

$contact2 = new Contact();
$contact2->name = 'anotherTest';

$manager->pushMultipleToIndices([$contact1, $contact2]);

手动删除

通过使用 removeFromIndices() 实例方法来触发删除。

$contact = Contact::findOne(['name' => 'test');
$contact->removeFromIndices();

或者使用服务

$contact = Contact::findOne(['name' => 'test']);
$manager->removeFromIndices($contact);

您还可以使用服务的 removeMultipleFromIndices() 方法批量删除同一类的多个模型。

$contacts = Contact::find()->where(['type' => Contact::TYPE_AWESOME])->all();
$manager->removeMultipleFromIndices($contacts);

手动更新

通过使用 updateInIndices() 实例方法来触发更新。

$contact = Contact::findOne(['name' => 'test']);
$contact->updateInIndices();

或者使用服务

$contact = Contact::findOne(['name' => 'test']);
$manager->updateInIndices($contact);

使用该服务的updateMultipleInIndices()方法也可以批量更新同一类别的多个模型。

$contacts = Contact::find()->where(['type' => Contact::TYPE_AWESOME])->all();
foreach($contacts as $contact) {
  $contact->type = Contact::TYPE_NOT_SO_AWESOME;
}
$manager->updateMultipleInIndices($contacts);

重新索引

为了安全地重新索引所有ActiveRecord模型(将索引移动到临时索引然后移动到当前索引),可以使用leinonen\Yii2Algolia\AlgoliaManager::reindex()方法。

$manager->reindex(Contact::class);

如果您喜欢Yii的风格,也可以使用ActiveRecord类的静态方法。

Contact::reindex();

后台重新索引是通过分块处理给定类别的所有ActiveRecord模型来完成的,每次500个对象。这意味着即使对于非常大的数据集,也可以安全地使用重新索引,而不会消耗太多内存。只需注意Algolia配额。

通过ActiveQuery重新索引

如果您需要将许多相关关系索引到Algolia,可以使用leinonen\Yii2Algolia\AlgoliaManager类中找到的强大reindexByActiveQuery()方法。

$contactsQuery = Contact::find()->joinWith('company')->where(['company_name' => 'Algolia']);
$manager->reindexByActiveQuery($contactsQuery);

reindexByActiveQuery()方法也使用后台分块,因此可以安全地对大数据集进行查询。要重新索引的索引将根据查询模型的查询结果解决。

要将关系索引到Algolia,当然需要修改ActiveRecord模型的getAlgoliaRecord()fields()方法。Yii提供了一个方便的isRelationPopulated()方法来自定义此操作。

class Contact extends ActiveRecord implements SearchableInterface
{
   use Searchable;
   
   /**
    * {@inheritdoc}
    */
   public function getAlgoliaRecord()
   {
       $record = $this->toArray();
       
       if($this->isRelationPopulated('company')) {
           $record['company'] = $this->company->toArray();
       }
       
       return $record;
   }
}
使用一组显式的SearchableModels进行重新索引

还可以显式定义应重新索引的对象。这可以通过使用leinonen\Yii2Algolia\AlgoliaManager类中的reindexOnly()方法来完成。

$contacts = Contact::find()->where(['type' => Contact::TYPE_AWESOME])->all();
$manager->reindexOnly($contacts);

在后台,该方法会确定需要重新索引的索引,因此该数组必须只包含同一类别的模型。如果以这种方式获取大量ActiveRecords,请务必注意内存消耗。

清除索引

要清除ActiveRecord同步到的索引,请使用leinonen\Yii2Algolia\AlgoliaManager类中的clearIndices()方法。

$manager->clearIndices(Contact::class);

如果您喜欢Yii的风格,也可以使用ActiveRecord类的静态方法。

Contact::clearIndices();

自动索引

另一个解决方案是将leinonen\Yii2Algolia\ActiveRecord\SynchronousAutoIndexBehavior行为附加到ActiveRecord模型。然后,当模型被创建、更新或删除时,该行为将自动触发。当然,模型需要通过提及的特质或自定义方法实现leinonen\Yii2Algolia\SearchableInterface

请注意,每当指定的ActiveRecord模型发生任何变化时,Algolia API都将单独调用。这可能会引起性能问题。目前,Yii2没有提供开箱即用的队列,因此异步更新不可用。

配置

use leinonen\Yii2Algolia\ActiveRecord\Searchable;
use leinonen\Yii2Algolia\SearchableInterface;
use leinonen\Yii2Algolia\ActiveRecord\SynchronousAutoIndexBehavior;
use yii\db\ActiveRecord;

class Contact extends ActiveRecord implements SearchableInterface
{
    use Searchable;
    
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            SynchronousAutoIndexBehavior::class,
        ];
    }
}

您还可以通过props afterInsertafterUpdateafterDelete显式关闭插入、更新或删除事件。

public function behaviors()
{
    return [
        [
            'class' => SynchronousAutoIndexBehavior::class,
            'afterInsert' => false,
            'afterUpdate' => false,
        ],
    ];
}

后端搜索

Algolia一样,我强烈建议使用Algolia的JavaScript客户端以获得最佳的搜索体验。但是,您可以使用一些辅助工具在PHP端进行搜索。

通过服务

$manager->search(Contact::class, 'John Doe');

该方法也接受可选的搜索参数

$manager->search(Contact::class, 'John Doe', ['hitsPerPage' => 2, 'attributesToRetrieve' => 'name,address']);

使用具有leinonen\Yii2Algolia\ActiveRecord\Searchable特质的ActiveRecord类也可以进行搜索。

Contact::search('John Doe');
Contact::search('John Doe', ['hitsPerPage' => 2, 'attributesToRetrieve' => 'name,address']);

使用多个环境

您可以使用以下配置自动将所有索引名称前缀为当前App环境:

use leinonen\Yii2Algolia\AlgoliaComponent;
...
'bootstrap' => ['algolia'],
'components' => [
    'algolia' => [
        'class' => AlgoliaComponent::class,
        'applicationId' => 'test',
        'apiKey' => 'secret',
        'env' => YII_ENV
    ],
],

然后,当使用来自leinonen\Yii2Algolia\AlgoliaManager的任何辅助方法时,环境将添加到索引名称前。另外,使用leinonen\Yii2Algolia\Searchable特质上的辅助方法也将正常工作。注意:如果您直接使用来自官方Algolia客户端的方法,则环境配置将不会生效。

贡献

欢迎提交拉取请求!请查看CONTRIBUTING.md文档以获取一些说明。