【发布时间】:2021-08-27 05:48:46
【问题描述】:
这是我的问题:我有一个文档(我们称之为根),其中包含另一个文档(棒)的数组,其中包含另一个文档(叶子)的另一个数组。
或者简单地说:root{stickChain[leaveschain1[leaf1,leaf2],leaveschain2[leaf1,leaf2]]}
我可以访问 root _id、stick _id 或识别每个文档所需的任何内容。
基本上,到目前为止,我取得的最佳结果是,在创建叶子文档时,将其存储在与棍子相同的级别,或者换句话说,我是在根目录中创建叶子数组。
我正在使用 javascript 并使用猫鼬
这是我用过的线:
db.collection('root').findOneAndUpdate({ _id: root.id, "stick._id":expTemp._id },{stickChain:{$push: {"leavechain.$": leaf}}})
这给了我这个结果:root{ leavesChain[leaf1,leaf2],stickchain[1,2,3] }
I've come across something new to me(从 Mongodb 3.6 开始有一种处理数组数组的新方法),这是我尝试过的:
try{ db.collection('root').findOneAndUpdate(
{ _id: root.id, "stick._id":expTemp._id },
{$push: {"stickChain.$[xpc].leavesChain.$[qac]": leaf}},
{ arrayFilters: [ { "xpc._id": user._id } , { "qac._id": expTemp._id } ]})}
更新
try{ db.collection('root').findAndModify(
{$push: {"root.$[cv].stickChain.$[xpc].leavesChain.$[qac]": leaf}},
{ arrayFilters: [ {"cv._id":user.cv} ,{ "xpc._id": user._id } , { "qac._id": expTemp._id } ],
upsert:true})
.catch(error => console.error(error))
}catch{}
这给了我一种新的错误:MongoError: 必须指定 update 或 remove=true
问题是我不熟悉如何做,但我知道我想做什么:我想在 MongoDB 中获取的文档中的特定数组中插入一个“叶子”。也许不是最佳实践,所以欢迎任何提示:)
【问题讨论】:
-
我刚刚发布了另一个类似问题的答案。您应该不将数组放入文档内的数组中。最好使用其他模型。你会遇到查询和更新的问题,更不用说它没有经过优化。祝你好运!
-
好吧,那么我应该使用类似的东西: root[stickChain _id] 然后 stick[leavesChain[leaf]] ?我的意思是提取一定程度的“嵌套”?那是如何优化的?我真的很想知道它是如何工作的,如果你能简要解释一下,我可以从现在开始避免这种不良做法:)
-
问题是,如果您尝试搜索某些内容,适配器将遍历所有文档,然后是所有第一级文档,然后是所有第二级文档。这基本上就是你所拥有的一切。如果你只是拆分它们,那么你会跳过一个非常重要的遍历级别。也不可能完全同时(只是部分地)做到这一点。我的意思是你得到一个文档,然后你开始搜索它的第一个 lvl 子文档。然后对于每个子文档,您将获得所有子子文档。什么也没找到,所以你回到集合中的第二个文档...
-
如果你得到了这么多层次的嵌套,你通常会将它们分成单独的集合并使用引用。它有点像传统的关系数据库,但连接越少越好。然后按 id 索引第二个表,这意味着当您获得一个文档时,您可以说“给我该文档的任务列表,该列表的 id 为 5”。由于索引,它非常快,因此您再次跳过整个遍历。它就像一棵树,你拥有的数组越多,分支就越多。文档应尽可能平坦。祝你好运!
-
这是我刚刚找到的一本好书,它基本上总结了我所说的,但以更好的方式:docs.atlas.mongodb.com/schema-suggestions/…
标签: javascript node.js arrays mongodb crud