Як сортує записи MongoDB, коли не вказано порядок сортування?


103

Коли ми запускаємо запит Mongo find () без вказаного порядку упорядкування, що використовує внутрішня база даних для сортування результатів?

Відповідно до документації на веб-сайті mongo :

При виконанні пошуку () без параметрів база даних повертає об'єкти у прямому природному порядку.

Для стандартних таблиць природний порядок не є особливо корисним, оскільки, хоча замовлення часто близьке до порядку вставки, воно не гарантується. Однак для закритих колекцій природним порядком гарантується порядок вставки. Це може бути дуже корисно.

Однак для стандартних колекцій (без обмежених колекцій) яке поле використовується для сортування результатів? Це поле _id чи щось інше?

Редагувати:

В основному, я думаю, те, що я намагаюся отримати, це те, що якщо я виконую наступний пошуковий запит:

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

У двох різних моментах часу: t1 і t2 , я отримаю різні набори результатів:

  1. Коли не було додаткових записів між t1 & t2?
  2. Коли з'явилися нові записи між t1 & t2?
  3. Є нові індекси, додані між t1 та t2?

Я провів кілька тестів на базі даних temp, і отримані нами результати однакові ( так ) для всіх 3 випадків - але я хотів бути впевненим, і я впевнений, що мої тестові справи були не дуже ретельними.

Відповіді:


121

Який порядок сортування за замовчуванням, коли жоден не вказаний?

Внутрішній порядок сортування за замовчуванням (або природний порядок ) - це не визначена деталь реалізації. Підтримка порядку - це додаткові накладні витрати на двигуни зберігання, а API MongoDB не передбачає передбачуваності поза явним sort()або особливим випадком наборів фіксованого розміру з обмеженими розмірами, які пов'язані з обмеженнями використання . Для типових навантажень бажано, щоб двигун пам’яті намагався повторно використовувати наявний попередньо виділений простір і приймати рішення про те, як найбільш ефективно зберігати дані на диску та в пам’яті.

Без будь-яких критеріїв запитів результати повертаються двигуном зберігання в природному порядку (він же в тому порядку, в якому вони були знайдені ). Порядок результатів може збігатися з порядком вставки, але ця поведінка не гарантована і на неї не можна покластися (окрім обмежених колекцій).

Деякі приклади, які можуть вплинути на зберігання (природне) замовлення:

  • WiredTiger використовує інше представлення документів на диску в порівнянні з кешем пам'яті, тому природне впорядкування може змінюватися на основі внутрішніх структур даних.
  • Оригінальний механізм зберігання даних MMAPv1 (вилучений у MongoDB 4.2) виділяє простір записів для документів на основі правил прокладки. Якщо документ перевищує виділений на даний момент простір запису, це вплине на розташування документа (та природне впорядкування). Нові документи також можна вставити у сховище, позначене для повторного використання через видалені або переміщені документи.
  • Реплікація використовує ідентичний потенціал формату oplog , щоб послідовно застосовувати операції запису для всіх наборів реплік. Кожен член набору реплік підтримує локальні файли даних, які можуть змінюватися в природному порядку, але матимуть однакові результати, коли застосовуються оновлення oplog.

Що робити, якщо використовується індекс?

Якщо використовується індекс, документи повертаються в тому порядку, в якому вони були знайдені (що обов'язково відповідає порядку вставки або порядку вводу / виводу). Якщо використовується більше одного індексу, то порядок внутрішньо залежить від того, який індекс вперше ідентифікував документ під час дедублювання.

Якщо ви хочете передбачувати порядок сортування, ви повинні включити явний sort()запит і мати унікальні значення для вашого ключа сортування.

Як обмежені колекції підтримують порядок вставки?

Виняток із застосування, відзначений для природного порядку в обмежених колекціях, застосовується спеціальними обмеженнями використання: документи зберігаються в порядку вставки, але існуючий розмір документа не може бути збільшений, а документи не можна явно видалити. Замовлення - це частина дизайну з обмеженою колекцією, що забезпечує перше «найстаріші документи».


4
Так це означає, що якщо я запускаю одну і ту ж команду find: db.collection.find ({"x": y}). Skip (20000) .limit (1000) у двох різних моментах часу, я отримаю різний результат набори? Що станеться, якщо між двома командами не було записів?
saurabhj

6
@saurabhj: Додано кілька прикладів, які впливатимуть на природний порядок. Якщо документи переміщено / видалено, ви можете отримати різні набори результатів. Якщо не було вставлених / оновлених / видалених документів, ви повинні отримати той самий результат. Додавання індексів не впливає на розташування документів на диску.
Стенні

7
Слід також додати застереження, що якщо ви використовуєте реплікацію, природне впорядкування може змінюватись між членами набору реплік.
Стенні

Хтось знає, як змусити будь-який із 2 коментарів, коментованих тут? Ми спробували змінити документи, але вони все ще повертаються в порядку вставки ... Мені цікаво, чи може природний порядок відрізнятися від порядку вставки.
Ферран Мейлінч

Забезпечення замовлення за замовчуванням (наприклад {createdAt: -1}) необхідно для реалізації оптимістичних моделей інтерфейсу користувача (оновлення списків даних у кеші, не чекаючи відповіді сервера після створення / оновлення / видалення). Інакше ви не можете співставити клієнтський оптимістичний порядок та порядок відповіді сервера.
Ерік Бурель

8

Він повертається у збереженому порядку (порядок у файлі), але не гарантується, що вони є у вставленому порядку. Вони не сортуються за полем _id. Іноді це може виглядати так, ніби він відсортований за порядком вставки, але він може змінитися в іншому запиті. Це не є надійним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.