Can MongoDB et ses pilotes conservent-ils la commande des éléments du document

Je envisage d'utiliser MongoDB pour stocker des documents incluant une liste de paires clés / valeur. La façon sûre, mais laide et gonflée de stocker ceci est comme

[ ['k1' : 'v1'] , ['k2' : 'v2'], ...] 

Mais les éléments du document sont intrinsèquement ordonnés dans la structure de données BSON sous-jacente, donc en principe:

 {k1 : 'v1', k2 : 'v2', ...} 

Cela devrait suffire. Cependant, je m'attends à ce que la plupart des liens linguistiques les interprètent comme des tableaux associatifs et, par conséquent, risquent de brouiller les commandes. Donc, ce que je dois savoir, c'est:

  • MongoDB s'engage- t-il à préserver l'ordre des articles de la deuxième forme.
  • Les liaisons linguistiques ont-elles une API qui peut l'extraire d'un formulaire ordonné, même si l'API "pratique" habituelle renvoie un tableau associatif.

Je suis surtout intéressé par Javascript et PHP ici, mais j'aimerais aussi connaître d'autres langues. Toute aide est appréciée, ou simplement un lien vers une documentation où je peux aller à RTM.

Non, MongoDB ne garantit pas la commande des champs :

"Il n'y a aucune garantie que l'ordre des champs soit cohérent, ou le même, après une mise à jour".

En particulier, les mises à jour sur place qui changent la taille du document changent habituellement la commande des champs. Par exemple, si vous $set un champ dont l'ancienne valeur était du type et la nouvelle valeur est NumberLong , les champs sont habituellement redistribués.

Cependant, les tableaux conservent la commande correcte:

 [ {'key1' : 'value1'}, {'key2' : 'value2'}, ... ] 

Je ne vois pas pourquoi c'est "laid" et "gonflé" du tout. Le stockage d'une liste d'objets complexes ne pouvait pas être plus simple. Cependant, abuser des objets en tant que listes est certainement laid: les objets ont une sémantique de tableau associatif (c.-à-d. Il ne peut y avoir qu'un champ d'un prénom), alors que les listes / tableaux ne sont pas:

 // 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" } ] } 

Gardez à l'esprit que MongoDB est une base de données objet, pas un magasin clé / valeur.

De Mongo 2.6.1, il conserve l'ordre de vos champs:

MongoDB conserve l'ordre des champs de document après les opérations d'écriture sauf pour les cas suivants:

  • Le champ _id est toujours le premier champ du document.
  • Les mises à jour qui incluent le renommage des noms de champs peuvent entraîner la réorganisation des champs dans le document.

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

L'un des points de la douleur est de comparer les documents entre eux dans la coquille.

J'ai créé un projet qui crée un mongorc.js personnalisé qui trie les clés de document par défaut pour vous quand elles sont imprimées, au moins vous pouvez voir ce qui se passe clairement dans le shell. C'est appelé Mongo Hacker si vous voulez lui donner un tourbillon.

Bien qu'il soit vrai que, à partir de Mongo 2.6.1, il conserve l'ordre, il faut toujours faire attention aux opérations de mise à jour.

Mattwad fait valoir que les mises à jour peuvent réorganiser les choses, mais il y a au moins une autre préoccupation dont je peux penser.

Par exemple $ addToSet:

https://docs.mongodb.com/manual/reference/operator/update/addToSet/

$ AddToSet lorsqu'il est utilisé sur des documents incorporés dans un tableau est décrit / illustré ici: https://stackoverflow.com/a/21578556/3643190

Dans la publication, mnemosyn explique comment $ addToSet ignore l'ordre lorsque l'on associe des éléments dans sa valeur profonde par comparaison de valeur.

($ AddToSet n'ajoute que des enregistrements lorsqu'ils sont uniques)

Ceci est pertinent si l'on a décidé de structurer des données comme ceci:

 [{key1: v1, key2: v2}, {key1: v3, key2: v4}] 

Avec une mise à jour comme celle-ci (notez l'ordre différent sur la documentation intégrée):

 db.collection.update({_id: "id"},{$addToSet: {field: {key2: v2, key1: v1} }}); 

Mongo verra cela comme un double et NE PAS cet objet sur le tableau.