augustdai/hyperf-scout-meilisearch

Hyperf MeiliSearch Scout provides a driver based solution to searching your Eloquent models.

Maintainers

Package info

github.com/augustdai/hyperf-scout-meilisearch

pkg:composer/augustdai/hyperf-scout-meilisearch

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-05-27 09:50 UTC

This package is not auto-updated.

Last update: 2026-05-27 13:04:52 UTC


README

[目录]

简介

本扩展包为 Hyperf 框架提供了类似 Laravel Scout 的 Meilisearch 集成,支持文档索引、搜索、批量更新和批量同步索引设置等。

  • 支持自定义索引名
  • 支持批量添加/更新/删除文档
  • 支持批量同步索引设置

环境要求

  • PHP >= 8.1
  • Hyperf >= 3.1

安装

composer require augustdai/hyperf-scout-meilisearch

配置

config/autoload/scout.php

use App\Model\Video;
use Hyperf\Scout\Provider\MeilisearchProvider;

return [
    'default' => env('SCOUT_ENGINE', 'meilisearch'),
    'chunk' => [
        'searchable' => 500,
        'unsearchable' => 500,
    ],
    'prefix' => env('SCOUT_PREFIX', ''),
    'soft_delete' => false,
    'concurrency' => 100,
    'engine' => [
        'meilisearch' => [
            'driver' => MeilisearchProvider::class,
            'host' => env('MEILISEARCH_HOST', 'http://127.0.0.1:7700'),
            'key' => env('MEILISEARCH_KEY', null),
            'index-settings' => [
                Video::class => [
                    'filterableAttributes' => ['id', 'type', 'created_at'],
                    'sortableAttributes' => ['id', 'sort', 'created_at'],
                    // 'searchableAttributes' => [], // 默认全部字段可搜索,需要限定时开启
                ],
            ],
        ],
    ],
];

.env

SCOUT_PREFIX=dev_
SCOUT_ENGINE=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=xxxxxxxxxxxxxxxxx

Model 配置

<?php

namespace App\Model;

use Hyperf\Scout\Searchable;

class Video extends Model
{
    use Searchable;

    public function searchableAs(): string
    {
        return 'Videos';
    }

    /**
     * 只返回需要索引的字段,减少索引体积和导入耗时。
     */
    public function toSearchableArray(): array
    {
        return [
            'id'         => $this->id,
            'title'      => $this->title,
            'content'    => $this->content,
            'created_at' => $this->created_at?->toDateTimeString(),
        ];
    }

    public function getScoutKeyName(): string
    {
        return $this->getKeyName();
    }
}

注意:getScoutKeyName 必须重写。 Hyperf 默认实现返回 table.column 格式(含点号),而 Meilisearch 不支持以点号作为主键字段名。

Hyperf 协程环境下的 MeilisearchProvider

在 Hyperf 协程(Swoole/Swow)环境中,Guzzle 的默认 curl handler 不是协程安全的,高并发导入时会出现 cURL error 0: unable to rewind body 错误。需要使用 Hyperf 提供的 HandlerStackFactory 替换默认 handler:

<?php

namespace Hyperf\Scout\Provider;

use GuzzleHttp\Client as GuzzleHttpClient;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Guzzle\HandlerStackFactory;
use Hyperf\Scout\Engine\Engine;
use Hyperf\Scout\Engines\MeilisearchEngine;
use Http\Factory\Guzzle\RequestFactory;
use Http\Factory\Guzzle\StreamFactory;
use Meilisearch\Client;
use Psr\Container\ContainerInterface;

class MeilisearchProvider implements ProviderInterface
{
    public function __construct(private ContainerInterface $container) {}

    public function make(string $name): Engine
    {
        $config = $this->container->get(ConfigInterface::class);
        $host = $config->get("scout.engine.{$name}.host");
        $key  = $config->get("scout.engine.{$name}.key");

        $stack = (new HandlerStackFactory())->create(
            ['max_connections' => 256],
            ['retry' => false]
        );

        $guzzle = new GuzzleHttpClient([
            'handler' => $stack,
            'headers' => ['Accept-Encoding' => 'identity'], // 禁用压缩,避免协程环境解压失败
            'expect'  => false,                              // 禁用 100-Continue,防止大请求体 rewind 失败
        ]);

        $client = new Client($host, $key, $guzzle, new RequestFactory(), [], new StreamFactory());

        return new MeilisearchEngine($client);
    }
}

使用

建立索引(首次使用)

php bin/hyperf.php meilisearch:index "App\Model\Video" --key=id

同步索引设置

同步 index-settings 中配置的 filterable/sortable/searchable 字段,无需传入模型名

php bin/hyperf.php meilisearch:sync-index-settings

全量导入数据

php bin/hyperf.php scout:import "App\Model\Video"

大数据量快速导入(推荐):

通过 --chunk 参数增大每批条数,配合 scout.concurrency 提升并发,可显著缩短导入时间。

php bin/hyperf.php scout:import "App\Model\Video" --chunk=5000

性能参考:

  • 默认配置(chunk=500, concurrency=100):约 1,800 条/秒
  • 推荐配置(chunk=5000, concurrency=200):约 5,000 条/秒

concurrencyconfig/autoload/scout.phpconcurrency 字段配置。

后台运行并记录日志:

nohup php bin/hyperf.php scout:import "App\Model\Video" --chunk=5000 > /tmp/scout_import.log 2>&1 &
tail -f /tmp/scout_import.log

删除索引数据

php bin/hyperf.php scout:flush "App\Model\Video"

删除索引

php bin/hyperf.php meilisearch:delete-index videos

搜索

详见 hyperf scout 官方文档:https://hyperf.wiki/3.1/#/zh-cn/scout

注意事项

  • 主键字段名不能含点号(.),必须重写 getScoutKeyName() 返回 getKeyName()
  • 索引的 primary key 一旦设置不可更改,需要删除索引重建
  • addDocuments 是 upsert 操作,重复导入同一主键只会覆盖,不会产生重复数据
  • toSearchableArray() 建议只返回需要搜索/过滤/排序的字段,避免索引体积过大

License

MIT