creatortsv/eloquent-elastic-sync

此包帮助同步将eloquent模型索引到Elasticsearch

dev-master 2020-08-29 19:24 UTC

This package is auto-updated.

Last update: 2024-09-12 15:09:47 UTC


README

此包帮助您将eloquent模型与Elasticsearch文档同步

tests License Latest Stable Version

先决条件

  • PHP >= 7.2

安装

  1. 运行composer命令
composer require creatortsv/eloquent-elastic-sync
  1. EloquentObservant特征添加到您将要与elasticsearch同步的eloquent模型中
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    /* ... */
    use EloquentObservant;
    /* ... */
}

配置

您可能希望创建config/elastic_sync.php配置文件或使用以下artisan命令从包中导入它

php artisan vendor:publish --provider="Creatortsv\EloquentElasticSync\EloquentElasticSyncProvider"

对于最小配置,您应该编辑config/elastic_sync.php配置文件中connections.default部分的hostport属性

<?php

return [

    /*
     * Describe different connections
     */
    'connections' => [

        /*
         * Connection name
         */
        'default' => [

            'host' => env('ELASTIC_HOST'),
            'port' => env('ELASTIC_PORT'),

        ],

    ],

];

如果您想使用默认的另一个连接,则在config/elastyc_sync.php文件的connections部分描述自己的连接,并更改config/elastyc_sync.php文件的connection属性

<?php

return [
    
    /*
     * Which connection settings will be used
     */
    'connection' => 'awesome_connection', // default

    /*
     * Describe different connections
     */
    'connections' => [

        /* ... */
        
        'awesome_connection' => [

            'host' => 'awesome.com',
            'port' => 9201,

        ],
        
        /* ... */

    ],
    
];

如果您想为eloquent模型使用不同的连接

  • config/elastyc_sync.php文件的connections部分描述一些eloquent模型的自定义连接
<?php

return [
    
    /*
     * Describe different connections
     */
    'connections' => [

        /* ... */
        
        'flights-connection' => [

            'host' => 'awesome.users.com',
            'port' => 9202,

        ],
        
        /* ... */

    ],

];
  • 覆盖Eloquent模型中的php protected static function boot(): void方法,并设置连接名称,如下所示
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    use EloquentObservant;
    
    protected static function boot(): void
    {
        parent::boot();

        static::elastic()->setConnection('flights-connection');
    }
    
    /* ... */
}

数据映射

默认情况下,Eloquent模型将与具有其自身属性(无关系)的Elasticsearch文档同步。但是,如果您想同步具有突变属性的模型,例如

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    use EloquentObservant;
    
    /* ... */
    
    /**
     * Get full name of the flight
     *  @return string
     */
    public function getFlightNameAttribute(): string
    {
        return $this->name . ' ' . $this->destination;
    }
    
    /* ... */
}

那么您应该将config/elastic_sync.php文件的use_mutated_fields属性更改为true

<?php

return [
    /* ... */
    
    'use_mutated_fields' => true,
    
    /* ... */
];

您可以为Eloquent模型使用自己的数据映射和索引名称,这些数据将用于与Elasticsearch索引|更新|删除操作交互。默认情况下,Eloquent模型的索引名称(如果indexes.default属性为null)等于模型的表名属性。您可以通过两种不同的方式完成此操作

  1. config/elastyc_sync.php文件的indexes部分描述数据映射并设置default选项。此外,可以为每个单独的模型描述数据映射
<?php

return [
    /* ... */
    
    /*
     * Describe different indexes & its fields
     */
    'indexes' => [
    
        'default' => 'my-index', // if it is null then attributes of model will be used
        
        /**
         * Index name it'll bwe used as index for the documents
         */
        'my-index' => [
        
            /**
             * Base mapping for models
             */
            'base_mapping' => [
            
                'id',
                'name,
            /** 'avatar' => 'avatar.safe_url', Dot anotation allowed for the relations */
            
            ],
            
            App\Flight::class => [
            
                /* ... This mapping will be merged with the base_mapping of the described index */
            
            ],
        
        ],
    
    ],
    
    /* ... */
];
  1. 使用Eloquent模型上的boot()方法配置其行为
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    use EloquentObservant;
    
    /* ... */
    
    protected static function boot(): void
    {
        parent::boot();

        /**
         * Use custom data mapping
         * Don't use real data, only field names
         */
        static::elastic()->setMapping(function (Model $model): array {
            return [
                /* Describe yor mapping here */
            ];
        });
        
        /**
         * This name will be used as index for the Elasticsearch document
         */
        static::elastic()->setIndexName('flights-index');
    }
    
    /* ... */
}

对于每个Eloquent模型类,您可以在索引文档中添加额外字段,如下所示

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    use EloquentObservant;
    
    /* ... */
    
    protected static function boot(): void
    {
        parent::boot();

        /**
         * Using callback
         */
        static::elastic()->addExtra('group', function (Model $model): array {
            return $model->getTable();
        });
        
        /**
         * Using simple assign action
         */
        static::elastic()->addExtra('my_field', 'my_value');
    }
    
    /* ... */
}

您还可以使用回调函数在将其发送到Elasticsearch文档之前修改字段和额外字段,如下所示

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Creatortsv\EloquentElasticSync\EloquentObservant;

class Flight extends Model
{
    use EloquentObservant;
    
    /* ... */
    
    protected static function boot(): void
    {
        parent::boot();

        /**
         * Modify group extra field for example
         * @param mixed $group It is value after data mapping operation
         * @param array $data All data values after data mapping operation
         */
        static::elastic()->addCallback('group', function ($group, array $data, Model $model) {
            return $group . ' company: ' . $model->company->name; // result: flights company: Some Company Name
        });
        
        /**
         * Another time
         */
        static::elastic()->addCallback('group', function ($group, array $data, Model $model) {
            return $group . ' fixed'; // result: flights company: Some Company Name fixed
        });
    }
    
    /* ... */
}

Artisan命令

工作中...