mongodb - 如何展开进一步包含数组的数组字段
问题描述
嗨,我有一个userAnswer schema
看起来像这样的
var userAnswer = mongoose.Schema({
'questionId' : { 'type' : mongoose.Schema.Types.ObjectId, 'ref': 'Question'},
'userId' : { 'type': mongoose.Schema.Types.ObjectId, 'ref' : 'User'},
'score' : 1
})
然后一个userAttempt schema
包含关于这个问题的尝试
var userAttempt = mongoose.Schema({
'userAnswerId' : { 'type' : mongoose.Schema.Types.ObjectId, 'ref' : 'UserAnswer'},
'attemptData' : [{
'userInputMCQ' : String,
'time' : Date
}],
})
最后usersnapshots schema
一个保存关于attemptData
字段中每个元素的快照userAttempt Schema
看起来像这样
var userAttemptSnapshot= mongoose.Schema({
userAttemptDataId : {type: mongoose.Schema.Types.ObjectId },
count : {type: Number, default: 1},
userData :[ {
value: String,
timeOfCreation : { type : Date, default : Date.now }
}]
},
{ timestamps: true }
);
现在我想以这样一种方式获取所有data
关于question
尝试的信息,即
所有documents
领域attempData
都是UserAttempt Schema
'attemptData' : [{
'userInputMCQ' : String,
'time' : Date
}],
attempt
以各自的snapshots
使用方式作为个人获取aggregation
我aggregation query
的是
db.useranswers.aggregate([
{ $match : { 'questionId' : ObjectId("5a2dfefd6dc3de029e488961"),'userId' :ObjectId("5a2cea6d6dc3de029e488814") }},
{ '$lookup' : {from: "userattempts",
localField: "_id",
foreignField: "userAnswerId",
as: "attempts"}},
{ '$unwind' : '$attempts'},
{'$unwind' : '$attempts.attemptData'}
//after this stage i will use lookup to get snapshot data but i dont get those attempts as individual documents so that i could use lookup here
})
编辑:
我的userAnswer
收藏是
{
"_id":ObjectId("5b4f359244781a45bcc98fcb") ,
"userId":ObjectId("5a2cea6d6dc3de029e488814"),
"questionId": ObjectId("5a631937e2509a3288171c37"),
}
UserAttempt
集合是
{
"_id":ObjectId("5b4f359204a7251ebcabef24"),
"attemptData":[
{
"_id" : ObjectId("5b4f359204a7251ebcabef23"),
"userInputMCQ" : "0"
"timeOfCreation" : ISODate("2018-07-18T18:11:54.855+05:30"),
},
{
"_id" : ObjectId("5b4f35bb04a7251ebcabef27"),
"userInputMCQ" : "0",
"timeOfCreation" : ISODate("2018-07-18T18:12:35.765+05:30"),
} ]
}
UserAttemptSnapshot collection is
{
"_id":ObjectId("5b4f359204a7251ebcabef25"),
"userAttemptId":ObjectId("5b4f359204a7251ebcabef23"),
"count" : 2,
"userData" : [ {
'value' : "Some String" ,
"_id":ObjectId("5b4f359204a7251ebcabef26")
},
{
'value' : "Some String" ,
"_id": ObjectId("5b4f359204a7251ebcabef27")
} ]
},
{
"_id":ObjectId("5b4f359204a7251ebcabef25"),
"userAttemptId":ObjectId("5b4f359204a7251ebcabef27"),
"count" : 1,
"userData" : [ {
'value' : "Some String" ,
"_id":ObjectId("5b4f359204a7251ebcabeaee")
},
]
}
我想要这样的输出
{
"_id":ObjectId("5b4f359244781a45bcc98fcb") ,
"userId":ObjectId("5a2cea6d6dc3de029e488814"),
"questionId": ObjectId("5a631937e2509a3288171c37"),
"attemptData": {
"_id" : ObjectId("5b4f359204a7251ebcabef23"),
"userInputMCQ" : "0"
"timeOfCreation" : ISODate("2018-07-18T18:11:54.855+05:30"),
"userAttemptId" : ObjectId("5b4f359204a7251ebcabef23"),
"count" : 2,
"userData" : [ {
'value' : "Some String" ,
"_id":ObjectId("5b4f359204a7251ebcabef26")
},
{
'value' : "Some String" ,
"_id": ObjectId("5b4f359204a7251ebcabef27")
} ]
},
},
{
"_id":ObjectId("5b4f359244781a45bcc98fcb") ,
"userId":ObjectId("5a2cea6d6dc3de029e488814"),
"questionId": ObjectId("5a631937e2509a3288171c37"),
"attemptData": {
"_id" : ObjectId("5b4f35bb04a7251ebcabef27"),
"userInputMCQ" : "0",
"timeOfCreation" : ISODate("2018-07-18T18:12:35.765+05:30"),
"userAttemptId":ObjectId("5b4f359204a7251ebcabef27"),
"count" : 1,
"userData" : [ {
'value' : "Some String" ,
"_id":ObjectId("5b4f359204a7251ebcabeaee")
},
]
}
}
解决方案
您可以在 3.6 中使用以下聚合。
db.useranswers.aggregate([
{"$lookup":{
"from": "userattempts",
"let": {"id":"$_id"},
"pipeline":[
{"$match":{"$expr":{"$eq":["$$id","$userAnswerId"]}}},
{"$unwind":"$attemptData"},
{"$lookup":{
"from": "userattemptsnapshots",
"localField": "attemptData._id",
"foreignField":"userAttemptId",
"as": "attemptData.attemptsnapshot"
}},
{"$unwind":"$attemptData.attemptsnapshot"},
{"$group":{
"_id":"$userAnswerId",
"attemptData":{
"$push":"$attemptData"
}
}}
],
"as": "attempts"
}},
{"$unwind":"$attempts"},
])
更新 3.4 版本
db.useranswers.aggregate([
{"$lookup":{
"from": "userattempts",
"localField": "_id",
"foreignField":"userAnswerId",
"as": "attempts"
}},
{"$unwind":"$attempts"},
{"$unwind":"$attempts.attemptData"},
{"$lookup":{
"from": "userattemptsnapshots",
"localField": "attempts.attemptData._id",
"foreignField":"userAttemptId",
"as": "attempts.attemptData.attemptsnapshot"
}},
{"$unwind":"$attempts.attemptData.attemptsnapshot"}
])
推荐阅读
- php - 从sql视图中选择时如何在laravel中修复“准备好的语句需要重新准备”
- java - 如何在线创建和验证 onedrive 或 sharepoint 的 webhook?
- json - REST API:更新 JSON 对象数组的最佳实践
- java - 在文件中的每个单词后添加空格(Java)
- python - 访问 Python 虚拟环境
- javascript - 如何在完整的日历 js 中将事件呈现到整个单元格?
- .net - 同时列出和上传 Blob
- c# - 将项目添加到我的数据库(DBContext - EF)时,它会将这些项目添加到表中的随机位置,而不是一个接一个地添加。出了什么问题?
- javascript - 如何在不使用 Javascript 在 firebase 中删除集合本身的情况下从集合中删除所有文档?
- spring-boot - 如何创建包含所有属性的文档,这些属性可以在我的 Spring Boot 应用程序的 `yaml` 文件中被覆盖?