查询嵌套的子文档数组
Query nested arrays of subdocuments
编辑:查询不应使用“&”字符。那些或用于更新。
答案:由 Gibbs 提供
correct:
const result : any = await mongoose.model('Events').update(
{
_id: eventId,
"groups._id": groupId,
"groups.users._id": userId
},
incorrect:
const result: any = await mongoose.model('Events').findOne(
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users": { _id: '5f270877b4942d2528885dbd' }
})
// OR:
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users._id" : '5f270877b4942d2528885dbd',
})
只有前两个谓词(eventId
和分组 [$_id]
)它 returns 事件。但是第三次断了。
有人知道为什么这个 returns null(对象 ID 直接从数据库复制)
谢谢!
{
"_id": ObjectId("5f270416e7964b20d6f8953d"),
"lastRounds": [],
"name": "EpicFest",
"start": 1596392488896.0,
"end": 1596392500896.0,
"groups": [
{
"_id": ObjectId("5f270416e7964b20d6f8953e"),
"name": "Vossius",
"users": [
{
"created": 1596393590778.0,
"sessionId": null,
"feedBack": {
"messagesSent": 0,
"messagesSentLiked": 0,
"messagesReceived": 0,
"messagesReceivedLiked": 0,
"userFeedbackReceived": [],
"chatFeedbackReceived": [],
"_id": ObjectId("5f270877b4942d2528885dbe")
},
"_id": ObjectId("5f270877b4942d2528885dbd"),
"image": "someAvatr",
"name": "hans",
"groupId": "5f270416e7964b20d6f8953e",
"results": []
},
]
},
{
"_id": ObjectId("5f270416e7964b20d6f8953f"),
"users": [],
"name": "Ignatius"
}
],
"results": [],
"theses": [],
"rounds": 10,
"schedule": [],
"__v": 4
}
db.collection.find({
_id: ObjectId("5f270416e7964b20d6f8953d"),
"groups._id": ObjectId("5f270416e7964b20d6f8953e"),
"groups.users._id": ObjectId("5f270877b4942d2528885dbd")
})
您尝试使用字符串 "5f270416e7964b20d6f8953e"
。应该是ObjectId
您可以使用 .
表示法访问嵌套元素或 $elemMatch
使用聚合管道根据内部sub-document进行抓取。
在第一个匹配阶段,按 eventId
过滤并在内部 groupId
上执行 $elemMatch。
接下来,展开 group
和 groups.user
.
Post 展开你将拥有一个平面对象结构,你可以再次对其应用过滤器,现在只需在 groups.user._id
上应用匹配阶段。
const pipeline = [
{
$match: {
_id: eventId,
groups: {
$elemMatch: mongoose.Types.ObjectId('5f270416e7964b20d6f8953e')
}
}
},
{
$unwind: '$groups'
},
{
$unwind: '$groups.users'
},
{
$match: {
'$groups.users._id': mongoose.Types.ObjectId('5f270877b4942d2528885dbd')
}
}
];
const result: any = await mongoose.model('Events').aggregate(pipeline).exec();
编辑:查询不应使用“&”字符。那些或用于更新。
答案:由 Gibbs 提供
correct:
const result : any = await mongoose.model('Events').update(
{
_id: eventId,
"groups._id": groupId,
"groups.users._id": userId
},
incorrect:
const result: any = await mongoose.model('Events').findOne(
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users": { _id: '5f270877b4942d2528885dbd' }
})
// OR:
{
_id: eventId,
"groups._id": "5f270416e7964b20d6f8953e",
"groups.$.users._id" : '5f270877b4942d2528885dbd',
})
只有前两个谓词(eventId
和分组 [$_id]
)它 returns 事件。但是第三次断了。
有人知道为什么这个 returns null(对象 ID 直接从数据库复制) 谢谢!
{
"_id": ObjectId("5f270416e7964b20d6f8953d"),
"lastRounds": [],
"name": "EpicFest",
"start": 1596392488896.0,
"end": 1596392500896.0,
"groups": [
{
"_id": ObjectId("5f270416e7964b20d6f8953e"),
"name": "Vossius",
"users": [
{
"created": 1596393590778.0,
"sessionId": null,
"feedBack": {
"messagesSent": 0,
"messagesSentLiked": 0,
"messagesReceived": 0,
"messagesReceivedLiked": 0,
"userFeedbackReceived": [],
"chatFeedbackReceived": [],
"_id": ObjectId("5f270877b4942d2528885dbe")
},
"_id": ObjectId("5f270877b4942d2528885dbd"),
"image": "someAvatr",
"name": "hans",
"groupId": "5f270416e7964b20d6f8953e",
"results": []
},
]
},
{
"_id": ObjectId("5f270416e7964b20d6f8953f"),
"users": [],
"name": "Ignatius"
}
],
"results": [],
"theses": [],
"rounds": 10,
"schedule": [],
"__v": 4
}
db.collection.find({
_id: ObjectId("5f270416e7964b20d6f8953d"),
"groups._id": ObjectId("5f270416e7964b20d6f8953e"),
"groups.users._id": ObjectId("5f270877b4942d2528885dbd")
})
您尝试使用字符串 "5f270416e7964b20d6f8953e"
。应该是ObjectId
您可以使用 .
表示法访问嵌套元素或 $elemMatch
使用聚合管道根据内部sub-document进行抓取。
在第一个匹配阶段,按 eventId
过滤并在内部 groupId
上执行 $elemMatch。
接下来,展开 group
和 groups.user
.
Post 展开你将拥有一个平面对象结构,你可以再次对其应用过滤器,现在只需在 groups.user._id
上应用匹配阶段。
const pipeline = [
{
$match: {
_id: eventId,
groups: {
$elemMatch: mongoose.Types.ObjectId('5f270416e7964b20d6f8953e')
}
}
},
{
$unwind: '$groups'
},
{
$unwind: '$groups.users'
},
{
$match: {
'$groups.users._id': mongoose.Types.ObjectId('5f270877b4942d2528885dbd')
}
}
];
const result: any = await mongoose.model('Events').aggregate(pipeline).exec();