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

Laravel多表搜索:合并产品与用户类型关联的查询结果

Laravel搜索结果合并方案

最优解:单数据库查询实现(推荐)

直接通过关联查询和条件分组,一次数据库查询就能获取所有符合要求的激活产品,避免多次查询和集合合并,效率更高。

代码实现

use Illuminate\Database\Eloquent\Builder;

$products = Product::query()
    // 先限定产品状态为Active
    ->where('status', 'Active')
    // 分组处理所有匹配条件(产品自身匹配 OR 用户类型匹配)
    ->where(function (Builder $query) use ($search, $search_any) {
        // 产品名称匹配
        $query->where('name', 'LIKE', "%{$search}%")
              // 产品slug匹配
              ->orWhere('slug', 'LIKE', "%{$search_any}%")
              // 关联用户的type字段匹配,返回该用户的所有激活产品
              ->orWhereHas('user', function (Builder $userQuery) use ($search_any) {
                  $userQuery->where('type', 'LIKE', "%{$search_any}%");
              });
    })
    ->get();

逻辑说明

  • 外层的where('status', 'Active')确保所有返回的产品都是激活状态;
  • 内层闭包通过orWhere整合三个匹配规则:产品名称匹配、产品slug匹配、用户类型匹配;
  • whereHas方法利用产品与用户的关联关系,直接筛选出归属符合type条件用户的产品。

备选方案:集合合并(适合需分开处理查询的场景)

如果必须分开执行两次查询,再合并结果,可以使用Laravel集合的merge方法,同时注意去重(避免同一产品因满足多个条件重复出现)。

代码实现

// 查询1:名称/slug匹配的激活产品
$products = Product::query()
    ->where(function ($query) use ($search, $search_any) {
        $query->where('name', 'LIKE', "%{$search}%")
              ->orWhere('slug', 'LIKE', "%{$search_any}%");
    })
    ->where('status', 'Active')
    ->get();

// 查询2:用户type匹配的用户发布的激活产品
$productNew = Product::query()
    ->whereHas('user', function ($userQuery) use ($search_any) {
        $userQuery->where('type', 'LIKE', "%{$search_any}%");
    })
    ->where('status', 'Active')
    ->get();

// 合并两个集合并按ID去重
$mergedProducts = $products->merge($productNew)->unique('id');

注意事项

  • unique('id')必须添加,否则同一产品若同时满足两个查询条件,会在结果中重复出现;
  • 这种方式会执行两次数据库查询,性能略低于单查询方案。

安全优化建议

直接拼接%{$search}%存在SQL注入风险,建议使用Laravel的参数绑定写法,示例:

// 替换直接拼接的写法
->where('name', 'LIKE', DB::raw('concat("%", ?, "%")'), [$search])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:15:35