¿Cómo ordena MongoDB los registros cuando no se especifica ningún orden de clasificación?

103

Cuando ejecutamos una consulta de Mongo find () sin ningún orden de clasificación especificado, ¿qué utiliza la base de datos internamente para ordenar los resultados?

Según la documentación en el sitio web de mongo :

Cuando se ejecuta find () sin parámetros, la base de datos devuelve objetos en orden natural hacia adelante.

Para tablas estándar, el orden natural no es particularmente útil porque, aunque el orden a menudo se acerca al orden de inserción, no se garantiza que lo sea. Sin embargo, para las colecciones limitadas, se garantiza que el orden natural será el orden de inserción. Esto puede ser muy útil.

Sin embargo, para las colecciones estándar (colecciones sin límite), ¿qué campo se utiliza para ordenar los resultados? ¿Es el campo _id o algo más?

Editar:

Básicamente, supongo que estoy tratando de llegar a eso si ejecuto la siguiente consulta de búsqueda:

db.collection.find({"x":y}).skip(10000).limit(1000);

En dos momentos diferentes en el tiempo: t1 y t2 , obtendré diferentes conjuntos de resultados:

  1. ¿Cuándo no ha habido escrituras adicionales entre t1 y t2?
  2. ¿Cuándo ha habido nuevas escrituras entre t1 y t2?
  3. ¿Hay nuevos índices que se han agregado entre t1 y t2?

Ejecuté algunas pruebas en una base de datos temporal y los resultados que obtuve son los mismos ( ) para los 3 casos, pero quería estar seguro y estoy seguro de que mis casos de prueba no fueron muy completos.

saurabhj
fuente

Respuestas:

121

¿Cuál es el orden de clasificación predeterminado cuando no se especifica ninguno?

El orden de clasificación interno predeterminado (u orden natural ) es un detalle de implementación indefinido . Mantener el orden es una sobrecarga adicional para los motores de almacenamiento y la API de MongoDB no exige la previsibilidad fuera de un caso explícito sort()o especial de colecciones limitadas de tamaño fijo que tienen restricciones de uso asociadas . Para cargas de trabajo típicas, es deseable que el motor de almacenamiento intente reutilizar el espacio preasignado disponible y tome decisiones sobre cómo almacenar datos en disco y en memoria de manera más eficiente.

Sin ningún criterio de consulta, el motor de almacenamiento devolverá los resultados en orden natural (también conocido como en el orden en que se encuentran ). El orden de los resultados puede coincidir con el orden de inserción, pero este comportamiento no está garantizado y no se puede confiar en él (aparte de las colecciones limitadas).

Algunos ejemplos que pueden afectar el orden de almacenamiento (natural):

  • WiredTiger utiliza una representación diferente de los documentos en disco en comparación con la caché en memoria, por lo que el orden natural puede cambiar según las estructuras de datos internas.
  • El motor de almacenamiento MMAPv1 original (eliminado en MongoDB 4.2) asigna espacio de registro para documentos según las reglas de relleno. Si un documento supera el espacio de registro asignado actualmente, la ubicación del documento (y el orden natural) se verá afectado. Los nuevos documentos también se pueden insertar en el almacenamiento marcado como disponible para su reutilización debido a documentos eliminados o movidos.
  • La replicación usa un formato de registro de operaciones idempotente para aplicar operaciones de escritura de manera consistente en los miembros del conjunto de réplicas. Cada miembro del conjunto de réplicas mantiene archivos de datos locales que pueden variar en orden natural, pero tendrán el mismo resultado de datos cuando se apliquen las actualizaciones de oplog.

¿Qué pasa si se usa un índice?

Si se utiliza un índice, los documentos se devolverán en el orden en que se encuentran (lo que necesariamente coincide con el orden de inserción o el orden de E / S). Si se utiliza más de un índice, el orden depende internamente de qué índice identificó por primera vez el documento durante el proceso de deduplicación.

Si desea un orden de clasificación predecible, debe incluir un explícito sort()con su consulta y tener valores únicos para su clave de clasificación.

¿Cómo mantienen las colecciones limitadas el orden de inserción?

La excepción de implementación indicada para el orden natural en colecciones limitadas se aplica mediante sus restricciones de uso especiales: los documentos se almacenan en orden de inserción, pero el tamaño del documento existente no se puede aumentar y los documentos no se pueden eliminar explícitamente. El pedido es parte del diseño de la colección limitada que garantiza que los documentos más antiguos "caduquen" primero.

Stennie
fuente
4
Entonces, ¿esto significa que si ejecuto el mismo comando de búsqueda: db.collection.find ({"x": y}). Skip (20000) .limit (1000) en dos puntos diferentes en el tiempo, obtendré un resultado diferente conjuntos? ¿Qué sucede si no ha habido escrituras entre los dos comandos?
saurabhj
6
@saurabhj: Se agregaron algunos ejemplos que afectarán el orden natural. Si los documentos se han movido / eliminado, puede obtener diferentes conjuntos de resultados. Si no ha habido inserciones / actualizaciones / eliminaciones de documentos, debería obtener el mismo resultado. Agregar índices no afecta la ubicación de los documentos en el disco.
Stennie
7
También debe agregar la advertencia de que si está utilizando la replicación, el orden natural puede variar entre los miembros del conjunto de réplicas.
Stennie
¿Alguien sabe cómo forzar alguno de los 2 puntos comentados aquí? Intentamos modificar los documentos, pero aún se devuelven en su orden de inserción ... Tengo curiosidad por saber si el orden natural puede ser diferente del orden de inserción.
Ferran Maylinch
Es necesario hacer cumplir un orden predeterminado (por ejemplo {createdAt: -1}) para implementar patrones de IU optimistas (actualizar listas de datos en la caché sin esperar la respuesta del servidor después de crear / actualizar / eliminar). De lo contrario, no puede coincidir con el orden optimista del lado del cliente y el orden de respuesta del servidor.
Eric Burel
8

Se devuelve en el orden almacenado (orden en el archivo), pero no se garantiza que estén en el orden insertado. No están ordenados por el campo _id. A veces puede parecer que está ordenado por el orden de inserción, pero puede cambiar en otra solicitud. No es confiable.

Parvin Gasimzade
fuente