Mongoose中如何通过嵌套关联查询文档?
Mongoose中如何通过嵌套关联查询文档?
嗨,我来帮你捋清楚这个问题~
首先得明白你之前的查询为什么没生效:你的Folder模型里只存了Video的ObjectId引用,并没有把Video的完整数据(包括它的access字段)嵌在Folder文档里。所以直接在Folder上查videos.access或者用$elemMatch,MongoDB根本不知道这些ObjectId对应的Video里有哪些Access,自然查不到结果啦。
针对这种跨集合的嵌套关联查询,有两种常用的解决办法,你可以根据自己的场景选:
方法一:使用聚合管道(Aggregation Pipeline)
用$lookup关联对应的集合,把Video的数据拉进来之后再筛选,一步到位:
const mongoose = require('mongoose'); const targetAccessId = '<你的目标Access文档ID>'; // 替换成实际的Access ID Folder.aggregate([ // 第一步:关联Video集合,把Folder里的videos对应的完整Video文档查出来 { $lookup: { from: 'videos', // 注意这里是MongoDB中的集合名称,不是你的模型名 localField: 'videos', foreignField: '_id', as: 'matchedVideos' // 关联后的Video数据会存在这个字段里 } }, // 第二步:筛选出那些matchedVideos中包含目标Access的Folder { $match: { 'matchedVideos.access': { $in: [mongoose.Types.ObjectId(targetAccessId)] } } }, // 可选:如果不需要返回完整的matchedVideos,可以用$project保留需要的字段 { $project: { _id: 1, videos: 1, // 这里加上你需要保留的其他Folder字段 } } ]) .then(matchedFolders => { console.log('符合条件的文件夹:', matchedFolders); }) .catch(err => { console.error('查询出错:', err); });
方法二:分步查询(先找Video再找Folder)
这种方式更直观,适合数据量不大的场景,性能也很稳定:
const mongoose = require('mongoose'); const targetAccessId = '<你的目标Access文档ID>'; // 第一步:先找到所有包含目标Access的Video的ID Video.find( { access: { $in: [mongoose.Types.ObjectId(targetAccessId)] } }, '_id' // 只需要返回_id字段就行 ) .then(videos => { // 提取所有符合条件的Video的ID数组 const videoIds = videos.map(video => video._id); // 第二步:找到包含这些Video的Folder return Folder.find({ videos: { $in: videoIds } }); }) .then(matchedFolders => { console.log('符合条件的文件夹:', matchedFolders); }) .catch(err => { console.error('查询出错:', err); });
小提醒
- 一定要把
<你的目标Access文档ID>替换成实际的Access文档_id,如果传入的是字符串类型,记得用mongoose.Types.ObjectId()转换一下,不然MongoDB识别不了。 - 如果你的集合名称和模型名不一样(比如模型是
Video,集合名是video),在$lookup的from字段里要写正确的集合名哦。
备注:内容来源于stack exchange,提问作者Hüseyn
相关产品推荐
相关产品推荐

