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

如何使用Mongoose实现MongoDB三个集合联查并单次获取所需数据

Mongoose 实现三集合关联查询方案

首先确认三个集合的 Mongoose Schema 定义参考如下,保证关联逻辑正常:

// User 模型定义
const userSchema = new mongoose.Schema({
  name: {
    firstname: String,
    lastName: String
  }
})
const User = mongoose.model('User', userSchema)

// Device 模型定义
const deviceSchema = new mongoose.Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  name: String,
  data: [{ X: Number, Y: Number }]
})
const Device = mongoose.model('Device', deviceSchema)

// Location 模型定义
const locationSchema = new mongoose.Schema({
  X: Number,
  Y: Number,
  adresse: String
})
const Location = mongoose.model('Location', locationSchema)

核心聚合查询代码如下,完全匹配你给出的 SQL 左连接逻辑:

// 注意将用户ID转为ObjectId类型,如果你存储的_id是字符串可跳过转换
const targetUserId = mongoose.Types.ObjectId('616b429e0de99f6f74f911b9')

const queryResult = await User.aggregate([
  // 1. 过滤指定ID的用户,对应SQL的WHERE条件
  { $match: { _id: targetUserId } },
  // 2. 左连Devices集合,对应第一个LEFT JOIN逻辑
  {
    $lookup: {
      from: 'devices', // 填MongoDB中集合的实际名称,默认是模型名小写加复数
      localField: '_id',
      foreignField: 'user',
      as: 'deviceList'
    }
  },
  // 3. 打平设备数组,保留无设备的用户数据
  {
    $unwind: {
      path: '$deviceList',
      preserveNullAndEmptyArrays: true
    }
  },
  // 4. 打平设备下的坐标数组,保留无坐标的设备数据
  {
    $unwind: {
      path: '$deviceList.data',
      preserveNullAndEmptyArrays: true
    }
  },
  // 5. 左连Locations集合,对应第二个LEFT JOIN,多条件匹配X和Y
  {
    $lookup: {
      from: 'locations',
      let: { pointX: '$deviceList.data.X', pointY: '$deviceList.data.Y' },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ['$X', '$$pointX'] },
                { $eq: ['$Y', '$$pointY'] }
              ]
            }
          }
        }
      ],
      as: 'locationInfo'
    }
  },
  // 6. 打平地址数组,保留无匹配地址的坐标数据
  {
    $unwind: {
      path: '$locationInfo',
      preserveNullAndEmptyArrays: true
    }
  },
  // 7. 字段投影,对应SQL的SELECT部分,只返回需要的字段
  {
    $project: {
      _id: 0,
      uName: '$name',
      dName: '$deviceList.name',
      adresse: '$locationInfo.adresse'
    }
  }
])

补充说明

  • 返回的queryResult就是符合要求的数据集,每个条目对应一条设备坐标匹配到的地址记录,若某一步关联无匹配,对应字段会为null,完全符合左连接特性。
  • 如果不需要保留无匹配的空数据,可以去掉$unwind配置里的preserveNullAndEmptyArrays: true,会自动过滤掉无关联的空条目。
  • $lookup的from字段必须填MongoDB数据库中集合的实际名称,如果你自定义过集合名,需要替换成你设置的名称。

内容的提问来源于stack exchange,提问作者Kisko Rick Barrisson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:45:04