搜索用的包

github地址:
https://github.com/sleimanx2/plastic#sugge...
使用说明(readme翻译了下):
Plastic 是 Elasticsearch ODM(Object Document Mapper 的简称)和 Laravel 的mapper。 通过提供:流畅的mapping语法、查询、存储eloquent模型,使得开发人员使用Elasticsearch更爽。

使用StyleCI自动纠正代码分格

这个包依然处于开发活跃期,随时可能修改。

对于 Elasticsearch v2 ,请使用0.4.0以下版本。

安装 Plastic

composer require sleimanx2/plastic

然后我们需要增加 plastic 服务提供者到 config/app.php :

Sleimanx2\Plastic\PlasticServiceProvider::class

最后我们需要执行:

php artisan vendor:publish

这个命令将创建一个配置文件 config/plastic.php 和一个映射目录 database/mappings (译者注:我的环境没生成这个目录)。

使用:

定义可搜索的模型

在你的模型中增加 Sleimanx2\Plastic\Searchable trait,开启搜索功能。

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
    ];
}

自定义索引类型名称
默认情况, Plastic 使用表名作为索引类型名称。你可以在模型中增加一个属性 $documentType 自定义它。

public $documentType = 'custom_type';

自定义索引名称
默认情况。 Plastic 使用配置文件中定义的所有名称。你可以在模型中增加一个属性 $documentIndex 自定义它。

public $documentIndex = 'custom_index';

保存所有内容
当你保存或者删除模型数据的时候, Plastic 自动同步模型数据到 elastic中。增加 public $syncDocument = false 到你的模型中,可以关闭这个功能 。

下面情况下,需要手动生成索引。

1 - 当你执行一个批量更新或者删除的时候,没有 Eloquent 事件被触发,所以索引文档不会被生成。

2 - Plastic 还没有关联到模型事件,所以当你更新一个关联模型内容的时候,你应该考虑更新父文档。

保存一个文档

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

搜索

Plastic 提供了一个良好的语法查询 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();

Check out this documentation of supported search queries within Plastic and how to apply unsupported queries.

Change index on the fly
To switch to a different index for a single query, simply use the index method.

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

Check out this documentation of supported aggregations within plastic and how to apply unsupported aggregations.

Suggestions

Plastic::suggest()->completion('tag_suggest', 'photo')->get();

The suggestions query builder can also be accessed directly from the model as well:

//this be handy if you have a custom index for your model
Tag::suggest()->term('tag_term','admin')->get();

Model Mapping
Mappings are an important aspect of Elasticsearch. You can compare them to indexing in SQL databases. Mapping your models yields better and more efficient search results, and allows us to use some special query functions like nested fields and suggestions.

生成一个模型映射

php artisan make:mapping "App\User"

在 database/mappings 目录中,新的映射器将被替换。

映射结构
一个映射类包含一个 map 方法。这个方法是用来映射给定的模型字段的。

在 map 方法中,你可以使用 Plastic Map builder 去形象的创建字段映射。举个例子,让我们看看如何创建 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());
    }
}

看看这个文档,学习更多的映射构造器可用方法。

Run Mappings
命令行创建映射

php artisan mapping:run

Updating Mappings
你只是增加了一个字段的映射,执行:

php artisan mapping:rerun

已经存在的映射字段不能被更新或者删除,所以你需要使用下面的技术更新已经存在的字段。

1 - 创建一个新的索引
你可以创建一个新的 Elasticsearch 索引,重新生成映射。映射生成好后,你可以使用 bulkSave 方法同步到 Elasticsearch。

2 - 使用别名
推荐创建带别名的 Elasticsearch index ,这样不停机的情况下,你可以轻松更新模型映射。看这个了解详情:

https://www.elastic.co/blog/changing-mappi...

索引文档生成

通过执行命令行,搜索的模型 可以生成索引文档:

php artisan plastic:populate [--mappings][--index=...][--database=...]
--mappings Create the models mappings before populating the index
--database=... Database connection to use for mappings instead of the default one
--index=... Index to populate instead of the default one

在 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-p...

贡献

谢谢你的贡献,捐款指南可以在这里找到。

许可证

Plastic是使用麻省理工学院许可证的开源软件。

将要做的,包括:
Search Query Builder
implement Boosting query
implement ConstantScore query
implement DisMaxQuery query
implement MoreLikeThis query (with raw eloquent models)
implement GeoShape query
Aggregation Query Builder
implement Nested aggregation
implement ExtendedStats aggregation
implement TopHits aggregation
Mapping
Find a seamless way to update field mappings with zero downtime with aliases
General
Better query builder documentation

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

不错,最近刚好在做这个 :smiley:

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!