【laralve项目】深度使用elasticsearch

创建商品的索引

http://localhost:9200/goods/
在这里插入图片描述

然后添加文档

“analyzer”: “ik_smart” 代表这个字段需要使用 IK 中文分词器分词

还有有一些字段的类型是 keyword,这是字符串类型的一种,这种类型是告诉 Elasticsearch 不需要对这个字段做分词,通常用于邮箱、标签、属性等字段。

skus的字段类型是 nested,代表这个字段是一个复杂对象,由下一级的 properties 字段定义这个对象的字段。我们的『商品 SKU』明明是对象数组,为什么这里可以定义成对象?这是 Elasticsearch 的另外一个特性,每个字段都可以保存多个值,这也是 Elasticsearch 的类型没有数组的原因,因为不需要,每个字段都可以是数组

在这里插入图片描述

然后测试

注意需要重新打开tinker
$goods = App\Models\Goods::find(78)->toESArray();

在这里插入图片描述
然后把这条数据存储到elasticsearch
app(‘es’)->index([‘id’ => $goods[‘id’], ‘index’ => ‘goods’, ‘type’ => ‘_doc’, ‘body’ => $goods]);

在这里插入图片描述
然后就可以从elasticsearch中获取出来
app(‘es’)->get([‘index’ => ‘goods’, ‘type’ => ‘_doc’, ‘id’ => 78]);
在这里插入图片描述

给索引添加以存在的数据

关于数据的添加来源有两个点,一已经有的数据,而是后续添加的数据

  1. 同步已有的数据

同步已有的数据的方式建议采用命令;也就是artisan命令来实现;
现在虽然是在本地执行,但是项目会部署到服务器上,这个时候如果凭访问去控制器填充数据这很显然并是不一个很好地方式。

通常来说通过执行命令来实现我数据的同步会显得更加的快速。
php artisan make:command Elasticsearch/SyncGoods
在这里插入图片描述
在这个里边写上处理把已经存在的数据同步到elasticsearch

我们在写入商品数据的时候用的是 bulk() 方法,这是 Elasticsearch 提供的一个批量操作接口。设想一下假如我们系统里有数百万条商品,如果每条商品都单独请求一次 Elasticsearch 的 API,那就是数百万次 的请求,性能肯定是很差的,而 bulk() 方法可以让我们用一次 API 请求完成一批操作,从而减少请求次数的数量级,提高整体性能。

bulk() 方法的参数是一个数组,数组的第一维描述了我们要做的操作,第二行则代表这个操作所需要的数据,第三行操作描述,第四行数据,依次类推,当然如果是删除操作则没有数据行。我们这个代码里只有创建数据,因此都是每两行一组操作。

在这里插入图片描述

<?php

namespace App\Console\Commands\Elasticsearch;

use Illuminate\Console\Command;
use App\Models\Goods;

class SyncGoods extends Command
{
    protected $signature = 'es:sync-goods';
    protected $description = '将商品数据同步到 Elasticsearch';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        $this->info('正在导入商品数据....');
        // 使用 chunkById 避免一次性加载过多数据
        Goods::query()->with('skus')->chunkById(100, function ($goods) {
            // 初始化请求体
            $req = ['body' => []];
            // 遍历商品
            foreach ($goods as $value) {
                // 将商品模型转为 Elasticsearch 所用的数组
                $data = $value->toESArray();
                $req['body'][] = [
                    'index' => [
                        '_index' => 'goods',// 指定es 的索引
                        '_type'  => '_doc',
                        '_id'    => $data['id'],
                    ],
                ];
                $req['body'][] = $data;
            }
            try {
                // 使用 bulk 方法批量创建
                app('es')->bulk($req);
            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
        });
        $this->info('同步完成');
    }
}

执行命令:

php artisan es:sync-goods

在这里插入图片描述
然候使用head就可以查到
在这里插入图片描述

同步添加数据

接下来同步新增和修改的商品,因为是同步于商品的新增和修改所以最好的是创建一个事件或者队列完成。

这里可以使用异步操作
php artisan make:job SyncGoodsToEs
在这里插入图片描述
在这里插入图片描述

<?php

namespace App\Jobs;

use App\Models\Goods;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SyncGoodsToEs implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected  $goods;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Goods $goods)
    {
        $this->goods = $goods;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

        $data = $this->goods->toEsArray();
        app('es')->index([
            'index' => 'goods',
            'type' => '_doc',
            'id' => $data['id'],
            'body' => $data,
        ]);
    }
}

该事件的触发可以放在保存数据后执行,也就是点击添加商品的提交时触发
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咔咔-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值