Mongoose:如何结合另一集合的ObjectId-数字映射查询记录
实现用户物品清单关联查询的解决方案
核心思路
通过MongoDB聚合管道,先提取目标用户的库存数据,将items的Map结构转换为可处理的数组,再关联Collectible集合获取物品详情,最后整理成期望的输出格式。
具体代码实现
const mongoose = require('mongoose'); const { ObjectId } = mongoose.Types; const USER_ID = '目标用户的ID字符串'; // 替换为实际用户ID Inventory.aggregate([ // 筛选目标用户的库存记录 { $match: { owner: ObjectId(USER_ID) } }, // 将Map结构的items转为[{k: 物品ID, v: 数量}]的数组 { $project: { items: { $objectToArray: "$items" } } }, // 展开items数组,逐个处理每个物品条目 { $unwind: "$items" }, // 关联Collectible集合,获取物品的标题和图片信息 { $lookup: { from: "collectibles", // 对应Collectible模型的集合名,默认是小写复数形式 localField: "items.k", foreignField: "_id", as: "collectible" } }, // 展开关联得到的collectible数组(每个条目仅匹配一个物品) { $unwind: "$collectible" }, // 格式化输出字段,去掉不需要的_id,映射到期望的字段名 { $project: { _id: 0, title: "$collectible.title", image: "$collectible.image", amount: "$items.v" } } ]).exec((err, result) => { if (err) { console.error('查询出错:', err); return; } console.log('查询结果:', result); // 输出结果即为期望的格式 });
注意事项
- 确认
from字段的值与Collectible模型对应的MongoDB集合名称一致,Mongoose默认会将模型名转为小写复数(如模型名Collectible对应集合名collectibles),若自定义了集合名需替换为对应名称。 USER_ID需替换为实际的用户ID字符串,并且要通过mongoose.Types.ObjectId()转换为ObjectId类型,确保匹配正确。- 若目标用户不存在库存记录,查询结果会返回空数组,可根据业务需求添加空结果的处理逻辑。
内容的提问来源于stack exchange,提问作者ykn121
相关产品推荐
相关产品推荐

