我正在学习MongoDB,我注意到每当我对文档进行更新时,正在更新的字段被推送到订单的末尾,所以如果我有类似的东西:
db.collection.save({field1: value1, field2: value2, ..., field 10: value10});
db.collection.update({field1: value1}, {$set: {field2: new_value}});
然后如果你这样做:
db.collection.find();
它会显示:
{ "field1":"value1", ..., "field10":"value10", "field2":"new_value"}
您可以看到字段顺序如何更改将更新字段推送到文档末尾的位置。此外,文档本身也被推到了collectoin的末尾。我知道它是一个“无架构”的数据库,它可能不是一个大问题,但它看起来并不“漂亮”:)。有没有办法在不更改订单的情况下进行就地更新?
答案 0 :(得分:20)
MongoDB根据特定的填充因子为新文档分配空间。如果您的更新增加了文档的大小超出最初分配的大小,则文档将移动到集合的末尾。相同的概念适用于文档中的字段。
答案 1 :(得分:10)
仅供参考,MongoDB 2.6次更新将保留字段顺序,但以下情况除外:
答案 2 :(得分:6)
基于JSON原则的MongoDB中的文档结构和集合结构。 JSON是键/值对的集(特别是用于集合的文档和索引/文档的fieldName / fieldValue)。从这个角度来看,你似乎根本不能依赖订单。
答案 3 :(得分:4)
对于文档,如果字段大小发生更改,它会写出一个新文档,其中的字段按字段名称排序。 使用以下语句可以看到此行为
案例1:字段大小没有变化,因此字段顺序没有变化
> db.testcol.find()
> db.testcol.save({a:1,c:3,b:2})
> db.testcol.find()
{ "_id" : ObjectId("4d5efc3bec5855af36834f5a"), "a" : 1, "c" : 3, "b" : 2 }
> db.testcol.update({a:1},{$set:{c:22}})
> db.testcol.find()
{ "_id" : ObjectId("4d5efc3bec5855af36834f5a"), "a" : 1, "c" : 22, "b" : 2 }
案例2:字段大小更改并且字段被重新编码
> db.testcol.find()
> db.testcol.save({a:1,c:"foo",b:2,d:4})
> db.testcol.find()
{ "_id" : ObjectId("4d5efdceec5855af36834f5e"), "a" : 1, "c" : "foo", "b" : 2, "d" : 4 }
> db.testcol.update({a:1},{$set:{c:"foobar"}})
> db.testcol.find()
{ "_id" : ObjectId("4d5efdceec5855af36834f5e"), "a" : 1, "b" : 2, "c" : "foobar", "d" : 4 }
您是否有特殊原因要求重新排序字段?以上是在OS X上使用1.8.0_rc0
答案 4 :(得分:2)
我创建了一个创建自定义mongorc.js的项目,默认为您排序文档键。它被称为Mongo Hacker
答案 5 :(得分:0)
拉曼,是的,我们不能对字典进行排序,但我们可以对dictonary的可视化进行排序,因此我们无法对文档的归档顺序进行排序,但我可以看到它是有序的。
例如在perl to_json中有选项规范
print to_json( $data, { utf8 => 1, pretty => 1, convert_blessed => 1, canonical => 1 } );
(规范选项)将通过对其键进行排序来输出JSON对象。这增加了相对较高的开销。 (当然,我们做了更多的排序操作......)
答案 6 :(得分:0)
为了使字段按我想要的顺序排列,我将具有属性的所有文档按正确的顺序插入到另一个Collection中。然后,我删除了旧的Collection,并将新的Collection重命名为原始名称。 显然首先要备份您的数据。