通过以下语句了解capped collections与MongoDB的用法,我想到了一个问题:
“插入后可以更新集合中的文档。但是,这些更新 无法导致文档增长。如果更新操作导致文档 为了超越原始大小,更新操作将失败。“
因此,如果没有完全解释原因,这本身听起来是合理的。它引导我思考,“如果我不希望文档增长,但可能添加更多信息(即:$ push to a array),那么将文档填充到我预期的大小会有什么问题。”< / p>
所以我的前提再次听起来很合理(无论如何),直到从FAQ on padding读取这个片段。
警告请勿在上限集合中手动填充文档。应用手册 填充到上限集合中的文档可能会破坏复制。另外,填充 如果重新同步MongoDB实例,则不会保留。
这再一次提出了我的问题,“为什么会这样?”或者具体说明:
为什么在这个“破解复制”中将文档填充到上限集合中?
文档是否遗漏了部分,说明了明显的原因?或者这只是封顶收藏内部工作的“黑暗魔法”吗? (可能与“填充不保留”部分相关)
或者这只是非常悲观,实际上没有理由你不能用这种方式填充? (至少在最近的版本中)。
如果有人可以阐明为什么这些陈述是正确的,那就很高兴。
PS虽然这不是严格编程,但我认为手动填充技术是编程技术,因此在这里留下了问题
答案 0 :(得分:2)
为什么在这个“破解复制”中填充加盖集合中的文档?
我认为文档可能有点过于谨慎(请参阅DOCS-1528)。 MongoDB无法知道字段padding_foobar
是用于“手动填充”还是包含系统关键信息,因此该技术通常可以正常工作, BUT
警告是这样的:MongoDB 初始复制将始终紧密打包数据,因此当在之后发生初始复制时,您更改了大小对于该文档,您稍后将无法再次该文档。
一个例子(注意:我将仅使用此处的内容大小,这是不正确的,因为字段名称,类型ID,终止符和字符串长度也占用空间,但这只会加强参数):
// 1. insert w/ 20 bytes of 'content'
insert({"name" : "john", "pad" : "0000000000000000"});
// 2. now we're performing an update, removing 16 bytes of padding, adding
// 3 bytes so we now have 7 bytes of 'content'
update({"name" : "john"}, {$unset: {"pad": 1}, $set: {"foo" : "bar"}});
// 3. at this point, we can easily grow the document again, as long as it doesn't
// grow past its original size of 20 bytes of content
update({"name" : "john"}, {$set: {"foo" : "barfoobar"}});
现在,当在步骤2之后发生初始复制时,将复制文档而不使用填充字段,因此复制副本上只有7个字节的“内容大小”。在这种情况下,步骤3中的操作将失败,因为它使文档越过文档的副本的“原始大小”,该文档与主文档的原始大小不匹配。
换句话说,当且仅当您的更新严格保持或减小对象大小时,该技术才适用。您是否可以确保在您的应用程序逻辑中(例如,因为只有这样的文档只有一次更新)是您可以回答的问题。