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

Laravel Jenssegers MongoDB中如何通过子查询获取关联用户文档

嘿,我来帮你搞定这个类似关系型JOIN的查询需求~结合你用的Laravel + Jenssegers MongoDB扩展,给你三种实用的解决方案:

方法一:分步查询(简单直接)

你已经拿到了to_id列表,接下来只需要用whereIn批量查询对应的User文档就行,还能自动去重:

// 第一步:提取所有关联的to_id(pluck比get更高效,直接返回字段数组)
$toIds = Message::where('from_id', $user->_id)->pluck('to_id');

// 第二步:批量查询对应的用户
$users = User::whereIn('_id', $toIds)->get();

这种方法优点是代码易懂,适合刚上手的场景,缺点是会发起两次数据库请求。

方法二:MongoDB聚合查询(高效单次请求)

用MongoDB的$lookup聚合操作(相当于SQL的LEFT JOIN),一次请求完成关联和查询,性能更好:

$users = Message::raw(function($collection) use ($user) {
    return $collection->aggregate([
        // 第一步:筛选出from_id匹配的消息
        [
            '$match' => [
                'from_id' => $user->_id
            ]
        ],
        // 第二步:关联users集合,匹配to_id和用户_id
        [
            '$lookup' => [
                'from' => 'users', // *注意这里是MongoDB的集合名,不是模型类名*
                'localField' => 'to_id',
                'foreignField' => '_id',
                'as' => 'recipient'
            ]
        ],
        // 第三步:展开recipient数组(因为lookup返回的是数组)
        [
            '$unwind' => '$recipient'
        ],
        // 第四步:把用户文档作为返回结果的根节点
        [
            '$replaceRoot' => ['newRoot' => '$recipient']
        ],
        // 第五步:去重,避免同一个用户因多条消息重复出现
        [
            '$group' => [
                '_id' => '$_id',
                'name' => ['$first' => '$name'],
                'email' => ['$first' => '$email']
            ]
        ]
    ]);
});

这种方法适合数据量较大的场景,只需要一次数据库交互,但写法相对复杂一点。

方法三:Eloquent关联(Laravel风格)

给Message模型定义关联关系,完全贴合Laravel的Eloquent用法,代码更优雅:
首先在Message模型里添加关联方法:

// app/Models/Message.php
public function recipient()
{
    // 关联User模型,外键是to_id,对应User的_id
    return $this->belongsTo(User::class, 'to_id', '_id');
}

然后就可以用预加载(with)来获取关联用户,再提取去重:

// 获取所有from_id匹配的消息,并预加载对应的接收用户
$messages = Message::where('from_id', $user->_id)->with('recipient')->get();

// 提取所有不重复的用户(unique按_id去重,values重置索引)
$users = $messages->pluck('recipient')->unique('_id')->values();

这种方法最符合Laravel的开发习惯,代码可读性高,维护起来也方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:40:20