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

Laravel Eloquent多条件关联查询:如何实现多属性同时筛选?

问题描述

我有一个inventory表,它与data表是一对多关联。正在开发筛选应用,用户可按颜色、材质等筛选库存,这些信息存储在data表以保证兼容性。

data表用于灵活扩展库存数据,字段如下:

inventory_id
key
value

需求:当用户筛选材质为棉且颜色为蓝色的库存时,仅返回同时满足两个条件的结果。

当前问题:现有查询返回的是材质为棉或颜色为蓝色的库存,代码如下:

$values = array_merge($materialValues, $colorValues);

Inventory::query()->whereHas('data', function ($q) {
    return $q->whereIn('key', [
        Enum::MATERIAL->key,
        Enum::COLOR->key
    ])->whereIn('value', $values);
})

尝试过以下写法,但查询报错:

Inventory::query()->whereHas('data', function ($q) {
    return $q->where('key', Enum::MATERIAL->key)
        ->whereIn('value', $materialValues)
        ->where('key', Enum::COLOR->key)
        ->whereIn('value', $colorValues);
})

需要保持查询为Builder实例,以便调用paginate()方法,请问用Eloquent能否实现该需求?

解决方案

可以实现,核心思路是对每个筛选维度单独调用whereHas——whereHas本身是AND逻辑,每个whereHas对应库存必须存在一条符合该维度条件的data记录,叠加后就能实现“同时满足所有筛选条件”的需求,且全程保持Builder实例可用。

示例代码:

$query = Inventory::query();

// 添加材质筛选条件
if (!empty($materialValues)) {
    $query->whereHas('data', function ($q) use ($materialValues) {
        $q->where('key', Enum::MATERIAL->key)
          ->whereIn('value', $materialValues);
    });
}

// 添加颜色筛选条件
if (!empty($colorValues)) {
    $query->whereHas('data', function ($q) use ($colorValues) {
        $q->where('key', Enum::COLOR->key)
          ->whereIn('value', $colorValues);
    });
}

// 调用分页,保持Builder实例特性
$results = $query->paginate(10);

原写法问题说明

  1. 第一种写法用whereIn('key', [...])+whereIn('value', [...]),本质是匹配单条data记录满足“key是材质/颜色且value在合并数组中”,只要有一条记录符合任一条件就会被选中,因此出现OR的效果。
  2. 第二种写法在同一个whereHas里同时要求key等于材质和颜色,单条data记录不可能同时满足两个不同的key值,因此会返回空结果或报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:42:36