我在Mongo中有以下数据结构:
{
"_id": "L7ucxMsTSfTDtctnt",
"lectures": [
{
"_id": "Tfr3DMxavZwP5yy6F",
"notes": [
{
"slide": 1,
"notes": "First Note",
"timestamp": "2015-05-18T20:18:36.510Z"
},
{
"slide": 2,
"notes": "Another note",
"timestamp": "2015-05-18T20:18:36.510Z"
}
]
}
]
}我试着做一个三重插入和一个数组推送。因此,如果外部_id不存在,则创建它,否则更新它。如果讲座_id不存在,请创建它,否则请更新它。如果笔记_id不存在,则创建对象并推送到笔记数组,否则更新它。
有没有可能做这么复杂的事情?我可以通过三个独立的步骤来完成它,但是我频繁地调用该函数,并且担心性能。
发布于 2015-05-19 18:44:22
如果你能在3个步骤中做到这一点,那将是非常令人印象深刻的……见鬼,仅仅是试图编写一个查询来返回具有该模式的单个notes对象,这就让我头疼不已。(试试看,你不会喜欢的)。
在第二层之后,对象模式的数组在mongo中开始变得非常笨重。通常更好的做法是使用新的集合或将其存储为子$elemmatch (doc.lectures['alsfjljfldjf5084534']),因为这样您就有了一个可引用的内存地址,而不是拼命地执行嵌套的nested。
不管怎样,为了回答你的问题,它只有1个upsert,因为它只有1个doc。当你考虑整个事情是1个文档时,就会变得更容易理解。只需获取文档并将其保存为JS对象。修改对象,然后插入整个对象。不要担心传输额外的重复数据字节。用疯狂的迭代查询来找到你想要编辑的文档中的特定点来困扰你的数据库,这是非常繁重的。
在本例中,您已经正确地对ER进行了建模(一个类有多个讲座,一个讲座有许多笔记),但是,根据您的查询模式,您可能希望将类放入它们自己的集合中,并将classID作为FK包含在您的classes集合中。然后,可以选择创建备注的子文档以便于访问。
要做到这一点,获得一个笔记对象就像Lectures.findOne({notesID: '234asfj'})一样简单。当然,你失去了原子性,但这是一个很小的代价。
编辑:
doc = {}; //empty object
subDocId = Random.id(); //ref for subdoc
doc[subDocId] = {
notes: 1,
text: 'foo'
}; // create subdoc
Lecture.insert(doc); //insert subdoc或
var doc = Lectures.findOne(); //get it
doc["Tfr3DMxavZwP5yy6F"] = {foo:1, bar:2} //mod it
Lecture.insert(doc); //upload ithttps://stackoverflow.com/questions/30312739
复制相似问题