tkrause/plastic

此包已被废弃,不再维护。未建议替代包。

Plastic 是 Laravel 的 Elasticsearch ODM 和映射器。它通过提供流畅的语法来映射、查询和存储eloquent模型,使开发者在使用 Elasticsearch 时体验更加愉快。

维护者

详细信息

github.com/tkrause/plastic

此包尚未发布版本,信息有限。


README

Plastic Logo

基于https://github.com/sleimanx2/plastic

Plastic 是 Laravel 的 Elasticsearch ODM 和映射器。它通过提供流畅的语法来映射、查询和存储eloquent模型,使开发者在使用 Elasticsearch 时体验更加愉快。

License Build Status StyleCI

此包仍在积极开发中,可能会有所变化。

对于 Elasticsearch v2,请参考版本 < 0.4.0。

安装 Plastic

composer require mxp100/plastic

如果您使用的是 Laravel >=5.5,服务提供者将 自动发现。否则,我们需要将 plastic 服务提供者添加到 config/app.php 下的 providers 键中。

Sleimanx2\Plastic\PlasticServiceProvider::class

最后,我们需要运行

php artisan vendor:publish

这将创建一个配置文件在 config/plastic.php,以及一个映射目录在 database/mappings

用法

定义可搜索的模型

要开始,通过添加 Sleimanx2\Plastic\Searchable 特性来启用模型中的搜索功能。

use Sleimanx2\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数据库中保存或删除模型时,塑料会自动将模型数据与弹性同步,但是可以通过在模型中添加 public $syncDocument = false 来禁用此功能。

需要注意的是,在多种场景下应手动更新文档

1 - 当您执行批量更新或删除时,不会触发Eloquent事件,因此文档数据不会同步。

2 - 塑料尚未监听相关模型的 eventos,因此当您更新相关模型的内容时,应考虑更新父文档。

保存文档

$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);

搜索模型内容

塑料提供了一个流畅的语法来查询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();

突出显示

$highlight = new Highlight();
$highlight->setTags(['<mark>'], ['</mark>']);
$highlight->addField('title', ['matched_fields' => ['title']]);
$highlight->addField('content', ['matched_fields' => ['content']]);

$highlight->setParameters([
    'require_field_match' => false,
    'force_source' => true,
]);


$search->query->addHighlight($highlight);

模型映射

映射是Elasticsearch的一个重要方面。您可以将它们与SQL数据库中的索引进行比较。映射您的模型会产生更好的搜索结果和更高的效率,并允许我们使用一些特殊的查询功能,如嵌套字段和建议。

生成模型映射

php artisan make:mapping "App\User"

新映射将放置在您的 database/mappings 目录中。

映射结构

映射类包含一个单独的方法 map。map 方法用于映射给定的模型字段。

map 方法中,您可以使用 Plastic Map 构建器以表达式创建字段映射。例如,让我们看看一个示例映射,该映射创建一个 Tag 模型映射

use Sleimanx2\Plastic\Map\Blueprint;
use Sleimanx2\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

填充索引

可以通过运行 Artisan 控制台命令来填充索引的可搜索模型

php artisan plastic:populate [--mappings][--index=...][--database=...]
  • --mappings 在填充索引之前创建模型映射
  • --database=... 用于映射的数据库连接,而不是默认连接
  • --index=... 要填充的索引,而不是默认索引

要重新创建文档的模型列表必须配置在每个索引的 config/plastic.php每个索引

    'populate' => [
        'models' => [
            // Models for the default index
            env('PLASTIC_INDEX', 'plastic') => [
                App\Models\Article::class,
                App\Models\Page::class,
            ],
            // Models for the index "another_index"
            'another_index' => [
                App\Models\User::class,
            ],
        ],
    ],

访问客户端

您可以通过以下方式访问 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 许可下许可的开源软件,许可协议可在 此处 查看。

待办事项

搜索查询构建器

  • 实现 Boosting 查询
  • 实现 ConstantScore 查询
  • 实现 DisMaxQuery 查询
  • 实现 MoreLikeThis 查询(使用原始 eloquent 模型)
  • 实现 GeoShape 查询

聚合查询构建器

  • 实现嵌套聚合
  • 实现扩展统计聚合
  • 实现TopHits聚合

映射

  • 找到一种无缝方式,使用别名以零停机时间更新字段映射

通用

  • 改进查询构建器文档