缩写架构:
const ThingSchema = new mongoose.Schema({
_id: {
type: String,
},
widgets: [{
user: {
type: Schema.Types.ObjectId,
ref: 'user',
},
lastViewedAt: {
type: Date,
},
}],
}, { _id: false });
鉴于userId
,您如何获得用户所属的所有Things
user
是深层嵌套对象数组中的子文档?
我已经介绍了在类似的“查找对象数组”问题的答案中找到的几种方法,这些问题表明.where
,$in
和.populate
match
无法得到的不只是Things
或nada的完整,未经过滤的集合。我欢迎反馈,为什么我上面尝试的特定方法对于我所追求的过滤结果的最终目标来说是一个糟糕/好的选择。
更新
我使用的部分解决方案aggregate
。首先,我必须$unwind
widgets
数组。在由$unwind
生成的结果集合中,然后$match
编辑了用户的_id
。
与其他查询不同,ObjectId
调用mongoose does not autocast _id
s进入mongo aggregate
的问题。我必须使用_id
明确转换mongoose.Types.ObjectId()
字符串。
const things = await Thing.aggregate([
{ $unwind: '$widgets' },
{ $match: { 'widgets._id': mongoose.Types.ObjectId(userId) } }
]);
这里唯一的问题是,在展开 widgets
数组的过程中,我丢失了完整的用户集合,只获得了我正在搜索的ID的单个用户现在在那个集合中。我现在需要做一些事情,比如抓住Thing
的ID并再次运行一个查询和.populate()
用户。
我在$filter
const things = await Thing.aggregate([
{ "$match": {
"widgets._id": { "$in": [ mongoose.Types.ObjectId(userId) ] }
}},
{ "$project": {
"widgets": {
"$filter": {
"input": "$widgets",
"as": "user",
"cond": { "$or": [{ "$eq": [ "$$user._id", mongoose.Types.ObjectId(userId) ] }] },
}
}
}}
]);