2011-12-20 7 views
13

Estoy considerando usar MongoDB para almacenar documentos que incluyen una lista de pares clave/valor. La manera más segura, pero fea e hinchado para almacenar esto es tanPuede MongoDB y sus controladores preservar el orden de los elementos del documento

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

Pero documento elementos se ordenan inherentemente dentro de la estructura de datos BSON subyacente, lo que en principio:

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

debería ser suficiente. Sin embargo, espero que la mayoría de los enlaces de lenguaje interpretarán estos como matrices asociativas y, por lo tanto, potencialmente codificarán el orden. Así que lo que necesito saber es:

  • por sí mismo no MongoDB promesa para preservar referencia de pedido de la segunda forma.
  • Los enlaces de idioma tienen alguna API que puede extraerla de forma ordenada, incluso si la API "conveniente" habitual devuelve una matriz asociativa.

Estoy especialmente interesado en Javascript y PHP aquí, pero también me gustaría saber sobre otros idiomas. Cualquier ayuda es apreciada, o solo un enlace a alguna documentación donde puedo ir a RTM.

+1

el foro de usuarios de mongodb es el mejor lugar para hacer estas preguntas; los desarrolladores de mongodb son muy útiles para responder preguntas como esta y podrían darte respuestas autorizadas. https://groups.google.com/forum/#!forum/mongodb-user –

+1

@JasonS gracias por eso. Una razón por la que pregunté aquí es que el problema involucra tantos idiomas/estándares diferentes que no sabía dónde buscar. Pero tienes razón, Mongo se sienta en el centro de todos. –

+1

Este es realmente el lugar más apropiado para preguntar. –

Respuesta

11

A partir de la versión 2.6 en adelante, MongoDB preserves the order of fields where possible. Sin embargo, el campo _id siempre aparece primero y los campos de cambio de nombre pueden ocasionar el reordenamiento. Sin embargo, generalmente trato de no confiar en detalles como este. A medida que la pregunta original menciona, también hay capas adicionales a tener en cuenta, que cada uno debe proporcionar algún tipo de garantía para la estabilidad del orden ...

respuesta original:

No, MongoDB does not make guarantees about the ordering of fields:

"No hay garantía de que la orden de campo sea constante o la misma después de una actualización".

En particular, las actualizaciones in situ que modifican el tamaño del documento generalmente cambiarán el orden de los campos. Por ejemplo, si $set un campo cuyo valor anterior era de tipo número y el nuevo valor es NumberLong, los campos generalmente se vuelven a solicitar.

Sin embargo, las matrices conservan ordenando correctamente:

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

no veo por qué esto es "feo" y "hinchado" en absoluto. Almacenar una lista de objetos complejos no podría ser más fácil. Sin embargo, abusar de objetos como listas es definitivamente feo: Los objetos tienen una semántica de matriz asociativa (es decir, sólo puede haber un campo de un nombre de pila), mientras que las listas/matrices no lo hacen:

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

Tenga en cuenta que es MongoDB una base de datos de objetos, no un almacén de claves/valores.

+1

Limpiar ... nada más que agregar .. +1 – RameshVel

+2

Bien, lo haré de esa manera. Sigo diciendo que es feo, pero es bastante razonable que MongoDB funcione de esa manera. "Los objetos tienen semántica de matriz asociativa" es un javascript-ismo (normalmente no usaría la palabra objeto para tales estructuras de datos). De mis lecturas (superficiales) sobre MongoDB, pensé que era una base de datos de documentos BSON, y BSON tiene una especificación muy clara, en la que se ordenan los elementos. En su lugar, MongoDB es una tienda de objetos parecidos a Javascript (o diccionarios tipo pitón) que usa BSON debajo del capó. Lo suficientemente justo. –

+0

"MongoDB no garantiza el orden de los campos" es incorrecto. MongoDB hace ciertas garantías estrictas sobre el orden de los campos. No lo garantiza después de cada operación (como "* después de una actualización *"), pero definitivamente garantiza. Dicho esto, dependiendo de los diccionarios, preservar el orden es una pesadilla y casi siempre es mejor evitarla, ya que los diccionarios nativos de la mayoría de los idiomas no lo hacen. –

0

Uno de los puntos fuertes de esto es la comparación de documentos entre sí en el shell.

He creado un proyecto que crea un mongorc.js personalizado que ordena las claves del documento por defecto cuando se imprimen, de modo que al menos se puede ver lo que está sucediendo claramente en el caparazón.Se llama Mongo Hacker si quieres darle un giro.

7

A partir de Mongo 2.6.1, que hace mantener el orden de los campos:

MongoDB conserva el orden de los campos de documentos siguientes operaciones de escritura a excepción de los siguientes casos:

  • El _id campo es siempre el primer campo en el documento.
  • Las actualizaciones que incluyen el cambio de nombre de los nombres de campo pueden dar como resultado el reordenamiento de los campos en el documento.

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

0

Aunque es cierto que, a partir de Mongo 2.6.1, no preservar el orden, todavía se debe tener cuidado con las operaciones de actualización.

mattwad señala que las actualizaciones pueden reordenar las cosas, pero hay al menos otra preocupación que se me ocurre.

Por ejemplo $ addToSet:

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

$ addToSet cuando se utiliza en documentos incrustados en una matriz se discute/ejemplificados aquí: https://stackoverflow.com/a/21578556/3643190

En el post, mnemosyn explica cómo $ addToSet ignora el orden cuando los elementos coinciden en su valor profundo por comparación de valores.

($ addToSet sólo añade registros cuando están única)

Esto es relevante si se decidió estructurar los datos de la siguiente manera:

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

Con una actualización como esto (nótese la orden de publicación diferente en el documento incrustado):

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

Mongo verá esto como un duplicado y NO este objeto para la matriz.

Cuestiones relacionadas