MongoDB及其驱动程序可以保留文档元素的顺序

Adr*_*ala 13 javascript php json mongodb bson

我正在考虑使用MongoDB来存储包含键/值对列表的文档.存储它的安全但丑陋和臃肿的方式是

[ ['k1' : 'v1'] , ['k2' : 'v2'],  ...]
Run Code Online (Sandbox Code Playgroud)

但是文档元素本质上是在底层BSON数据结构中排序的,因此原则上:

{k1 : 'v1', 
 k2 : 'v2',  ...}
Run Code Online (Sandbox Code Playgroud)

应该够了.但是我希望大多数语言绑定会将这些解释为关联数组,因此可能会对排序进行加扰.所以我需要知道的是:

  • MongoDB本身是否承诺保留第二种形式的项目排序.
  • 语言绑定是否有一些API可以提取它的有序形式 - 即使通常的"方便"API返回一个关联数组.

我最感兴趣的是Javascript和PHP,但我也想了解其他语言.感谢任何帮助,或者只是链接到我可以进入RTM的一些文档.

mne*_*syn 12

从版本2.6开始,MongoDB会尽可能保留字段的顺序.但是,该_id字段始终首先是重命名字段可以导致重新排序.但是,我一般不会依赖这样的细节.正如最初的问题所提到的那样,还需要考虑其他层次,每个层面必须为订单的稳定性提供某种保证......

原答案:

不,MongoDB 不保证字段的排序:

"无法保证更新后字段顺序一致或相同."

特别是,更改文档大小的就地更新通常会更改字段的顺序.例如,如果您$set的旧值的类型为number且新值为的NumberLong字段,则通常会重新排序字段.

但是,数组保持正确排序:

[ {'key1' : 'value1'}, {'key2' : 'value2'}, ... ]
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这个"丑陋"和"臃肿".存储复杂对象列表并不容易.但是,滥用对象作为列表肯定是丑陋的:对象具有关联数组语义(即,只能有一个给定名称的字段),而列表/数组则不:

// not ok:
db.foo2.insert({"foo" : "bar", "foo" : "lala" });
db.foo2.find();
{ "_id" : ObjectId("4ef09cd9b37bc3cdb0e7fb26"), "foo" : "lala" }

// a list can do that
db.foo2.insert({ 'array' : [ {'foo' : 'bar'}, { 'foo' : 'lala' } ]});
db.foo2.find();
{ "_id" : ObjectId("4ef09e01b37bc3cdb0e7fb27"), "array" : 
      [ { "foo" : "bar" }, { "foo" : "lala" } ] }
Run Code Online (Sandbox Code Playgroud)

请记住,MongoDB是一个对象数据库,而不是键/值存储.

  • 好的,我会这样做的.我仍然说它很难看,但MongoDB以这种方式工作是很合理的."对象具有关联数组语义"是一个javascript-ism(通常我不会将这个词对象用于这种数据结构).从我关于MongoDB的(表面)读数来看,我认为它是一个BSON文档的数据库 - 而且BSON有一个非常清晰的规范,其中元素是有序的.相反,MongoDB是一个类似Javascript的对象(或类似python的词典)的存储,它恰好使用了BSON.很公平. (2认同)

mat*_*wad 8

从Mongo 2.6.1开始,它会保持你的字段的顺序:

除了以下情况之外,MongoDB在写操作之后保留文档字段的顺序:

  • _id字段始终是文档中的第一个字段.
  • 包括重命名字段名称的更新可能导致重新排序文档中的字段.

http://docs.mongodb.org/manual/release-notes/2.6/#insert-and-update-improvements