In che modo MongoDB ordina i record quando non viene specificato alcun ordinamento?


103

Quando eseguiamo una query Mongo find () senza alcun ordinamento specificato, cosa utilizza internamente il database per ordinare i risultati?

Secondo la documentazione sul sito web di mongo :

Quando si esegue find () senza parametri, il database restituisce gli oggetti in ordine naturale.

Per le tabelle standard, l'ordine naturale non è particolarmente utile perché, sebbene l'ordine sia spesso vicino all'ordine di inserimento, non è garantito che lo sia. Tuttavia, per le Collezioni limitate, l'ordine naturale è sicuramente l'ordine di inserzione. Questo può essere molto utile.

Tuttavia, per le raccolte standard (raccolte non limitate), quale campo viene utilizzato per ordinare i risultati? È il campo _id o qualcos'altro?

Modificare:

Fondamentalmente, immagino che quello che sto cercando di ottenere è che se eseguo la seguente query di ricerca:

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

In due diversi momenti: t1 e t2 , otterrò diversi set di risultati:

  1. Quando non ci sono state scritture aggiuntive tra t1 e t2?
  2. Quando ci sono state nuove scritture tra t1 e t2?
  3. Sono stati aggiunti nuovi indici tra t1 e t2?

Ho eseguito alcuni test su un database temporaneo e i risultati che ho ottenuto sono gli stessi ( ) per tutti e 3 i casi, ma volevo essere sicuro e sono certo che i miei casi di test non fossero molto approfonditi.

Risposte:


121

Qual è l'ordinamento predefinito quando non viene specificato nessuno?

L'ordinamento interno predefinito (o ordine naturale ) è un dettaglio di implementazione non definito . Il mantenimento dell'ordine è un sovraccarico aggiuntivo per i motori di archiviazione e l'API di MongoDB non impone la prevedibilità al di fuori di un caso esplicito sort()o speciale di raccolte con limite di dimensioni fisse a cui sono associate limitazioni di utilizzo . Per i carichi di lavoro tipici è auspicabile che il motore di archiviazione tenti di riutilizzare lo spazio disponibile preallocato e prenda decisioni su come archiviare in modo più efficiente i dati su disco e in memoria.

Senza alcun criterio di query, i risultati verranno restituiti dal motore di archiviazione in ordine naturale (ovvero nell'ordine in cui vengono trovati ). L'ordine dei risultati può coincidere con l'ordine di inserzione ma questo comportamento non è garantito e non è affidabile (a parte le raccolte limitate).

Alcuni esempi che possono influire sull'ordine (naturale) di archiviazione:

  • WiredTiger utilizza una diversa rappresentazione dei documenti su disco rispetto alla cache in memoria, quindi l'ordine naturale può cambiare in base alle strutture di dati interne.
  • Il motore di archiviazione MMAPv1 originale (rimosso in MongoDB 4.2) alloca lo spazio di registrazione per i documenti in base alle regole di riempimento. Se un documento supera lo spazio di registrazione attualmente allocato, la posizione del documento (e l'ordine naturale) ne risentirà. Nuovi documenti possono anche essere inseriti nella memoria contrassegnati come disponibili per il riutilizzo a causa di documenti eliminati o spostati.
  • La replica utilizza un formato oplog idempotente per applicare le operazioni di scrittura in modo coerente tra i membri del set di repliche. Ogni membro del set di repliche conserva file di dati locali che possono variare in ordine naturale, ma avranno lo stesso risultato di dati quando vengono applicati gli aggiornamenti di oplog.

Cosa succede se viene utilizzato un indice?

Se viene utilizzato un indice, i documenti verranno restituiti nell'ordine in cui sono stati trovati (che corrisponde necessariamente all'ordine di inserimento o all'ordine di I / O). Se viene utilizzato più di un indice, l'ordine dipende internamente da quale indice ha identificato per primo il documento durante il processo di deduplicazione.

Se desideri un ordinamento prevedibile, devi includere un sort()elemento esplicito nella query e avere valori univoci per la chiave di ordinamento.

In che modo le raccolte con limite mantengono l'ordine di inserzione?

L'eccezione di implementazione annotata per l'ordine naturale nelle raccolte limitate è applicata dalle loro speciali restrizioni di utilizzo: i documenti vengono archiviati in ordine di inserimento ma le dimensioni dei documenti esistenti non possono essere aumentate ei documenti non possono essere eliminati esplicitamente. L'ordinazione fa parte del design della raccolta limitata che garantisce che i documenti più vecchi "invecchino" per primi.


4
Quindi questo significa che se eseguo lo stesso comando find: db.collection.find ({"x": y}). Skip (20000) .limit (1000) in due momenti diversi, otterrò risultati diversi imposta? Cosa succede se non ci sono state scritture tra i due comandi?
saurabhj

6
@saurabhj: aggiunti alcuni esempi che influenzeranno l'ordine naturale. Se i documenti sono stati spostati / eliminati, potresti ottenere diversi set di risultati. Se non ci sono stati inserimenti / aggiornamenti / eliminazioni di documenti, dovresti ottenere lo stesso risultato. L'aggiunta di indici non influisce sulla posizione dei documenti sul disco.
Stennie

7
Dovrebbe anche aggiungere l'avvertenza che se si utilizza la replica, l'ordine naturale può variare tra i membri del set di repliche.
Stennie

Qualcuno sa come forzare uno dei 2 punti qui commentati? Abbiamo provato a modificare i documenti ma sono ancora restituiti nel loro ordine di inserzione ... Sono curioso di sapere se l'ordine naturale può essere diverso dall'ordine di inserzione.
Ferran Maylinch

L'applicazione di un ordine predefinito (ad esempio {createdAt: -1}) è necessario per implementare i modelli di interfaccia utente ottimistici (aggiornare gli elenchi di dati nella cache senza attendere la risposta del server dopo una creazione / aggiornamento / eliminazione). Altrimenti non puoi abbinare l'ordine ottimistico lato client e l'ordine di risposta del server.
Eric Burel

8

Viene restituito nell'ordine memorizzato (ordine nel file), ma non è garantito che siano nell'ordine inserito. Non vengono ordinati in base al campo _id. A volte può sembrare che sia ordinato in base all'ordine di inserzione, ma può cambiare in un'altra richiesta. Non è affidabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.