You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Laravel Scout/Meilisearch时search后加where过滤子句报错如何解决?

问题原因

你遇到的报错是Laravel Scout + 旧版Meilisearch的过滤语法不兼容、配置缺失导致的,核心问题有两个:

  1. Laravel Scout的search()方法返回的是Scout查询构造器,不能直接混用Eloquent原生的where()逻辑,直接链式调用会触发语法冲突/逻辑错位
  2. Meilisearch 0.22版本需要显式声明可过滤字段,未提前配置的字段传入过滤规则会直接报错

解决方案

1. 配置Product模型的可过滤字段

在你的Product模型中添加如下配置,声明store_id为可过滤字段,同时确保toSearchableArray()方法返回的数组包含store_id:

<?php

namespace App\Models;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use Searchable;

    // 声明可过滤字段,Scout会自动同步到Meilisearch的过滤属性配置
    protected $filterable = [
        'store_id',
    ];

    // 可选:如果上面的配置不生效,可以重写该方法
    public function getFilterableKeys(): array
    {
        return ['store_id'];
    }

    // 确保搜索数组包含store_id
    public function toSearchableArray()
    {
        $array = $this->toArray();
        // 保留你原有逻辑,确保store_id在返回数组中即可
        return $array;
    }
}

配置完成后执行命令同步已有数据到Meilisearch:
php artisan scout:import "App\Models\Product"

2. 正确编写搜索过滤代码

两种适配旧版本的写法可直接使用:

// 写法1:用Scout原生where方法(推荐)
$products = Product::search($搜索关键词)
    ->where('store_id', 你要筛选的门店ID)
    ->get();

// 写法2:手动传入过滤规则适配0.22版Meilisearch(写法1报错时用)
$products = Product::search($搜索关键词, function ($engine, string $query, array $options) use ($storeId) {
    $options['filter'] = "store_id = {$storeId}";
    return $engine->search($query, $options);
})->get();

注意事项

  • 不要在get()之后再调用where,这种写法是在PHP内存中对结果集合做过滤,数据量大时性能极差
  • 不要在搜索链式调用中混用Eloquent的数据库查询方法(比如关联查询、数据库层的where条件),如果需要做数据库层二次过滤,可以先拿到Meilisearch返回的主键数组,再单独做Eloquent查询

内容的提问来源于stack exchange,提问作者Pedro Abreu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:45:05