我的结构如下所示:
course: { // course
id,
coursename,
sections: { // has an array of sections
section: {
id,
sectionname
cards: { // each section has an array of cards
card: {
id
cardname
}
}
}
}
}
现在,我获得了卡ID。假设cardID是301.我没有关于课程或卡存储部分的详细信息。我只有cardID。我想将卡片名称从“测试1”更新为“测试2”。
请提供一些有关如何仅更新cardId更新卡名称的信息。另外,请提供有关如何仅使用cardId访问单张卡的信息。
如果我运行以下查询:
db.course.find( {"sections.cards.id" : ObjectId("5859517447c4286d0f0639ee")},
{"sections.cards.$":1,_id:0})
返回整个section对象而不是返回单个卡。请提供一些有关如何仅使用cardId访问单张卡的信息。
我的文件示例:
{
"_id" : ObjectId("58595041cfdc46100f92a985"),
"modelType" : "Course",
"name" : "c1",
"sections" : [
{
"id" : ObjectId("5859504dcfdc46100f92a986"),
"name" : "s1",
"cards" : [
{
"id" : ObjectId("58595057cfdc46100f92a987"),
"name" : "card1",
},
{
"id" : ObjectId("5859506ccfdc46100f92a988"),
"name" : "card2"
}
]
}
]
}
请提供有关如何仅使用卡ID更新卡的信息。
假设我要更改卡的名称。我如何实现它?
答案 0 :(得分:3)
我希望这个答案足以满足您的需求:
db.collection.aggregate([
{$unwind: "$sections"}, // unwind the array
{$unwind: "$sections.cards"}, // unwind the array
{$match: {"sections.cards.id": ObjectId("5859506ccfdc46100f92a988")}}, // filter
{$project: {_id: 0, id: "$sections.cards.id", name: "$sections.cards.name"}} // cut and clear any property that you don't need
])
导致(我使用你的样本测试过):
{
"name" : "card2",
"id" : ObjectId("5859506ccfdc46100f92a988")
}
说明:
mongojs
或mongoose
等任何库,以及如何在各自的手册中执行此操作),unwind
操作filter文档生成Clear个文档。在这种情况下:哪张卡与您的ID匹配更新文档内的属性:
在不知道其索引的情况下更新数组内部的元素是不可能的,因此首先,您必须在其中找到其索引/位置。我能想到的最简单的方法是使用for
(因为你的是双层数组,我认为$lookup方法会复杂得多):
// first, find the document, where xxx is the target card ID
db.collection.find({'sections.cards.id': ObjectId("xxx")}, function(err, reply){
// iterates through the documents
for(var z = 0; z < reply.length; z++){
// iterates through the `sections`
for(var y = 0; y < reply[z].sections.length; y++){
// iterates through the `cards`
for(var x = 0; x < reply[z].sections[y].cards.length; x++){
if(reply[z].sections[y].cards[x].id.toString() === "xxx")
{
// do what you want to do the card here
reply[z].sections[y].cards[x].name = "updated name";
}
}
}
// save the updated doc one-by-one,
db.collection.update({_id: reply._id}, reply);
}
});
最佳解决方案
最好的解决方案是:首先没有这种文件。无架构数据库方法并不意味着您可以将所有内容放在文档中。您必须在下次设计文档架构时考虑数据的功能和可访问性。
您可以根据需要合理化文档。在这种情况下,您应该拆分course
文档,因为它明确card
属性应该是course
的独立集合。如果您担心自己需要加入这两个系列,请不要担心。由于3.2 mongodb为这种应用引入了sudo in php exec()。
它不仅可以让您的生活更轻松,还可以让mongo查询运行得更快。