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

103

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

Согласно документации на сайте mongo :

При выполнении find () без параметров база данных возвращает объекты в прямом естественном порядке.

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

Однако для стандартных коллекций (коллекций без ограничений) какое поле используется для сортировки результатов? Это поле _id или что-то еще?

Редактировать:

В принципе, я думаю, что я пытаюсь понять, что если я выполню следующий поисковый запрос:

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

В два разных момента времени: t1 и t2 , я получу разные наборы результатов:

  1. Когда не было дополнительных записей между t1 и t2?
  2. Когда были новые записи между t1 и t2?
  3. Есть новые индексы, которые были добавлены между t1 и t2?

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

саурабхдж
источник

Ответы:

120

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

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

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

Некоторые примеры, которые могут повлиять на порядок хранения (естественный):

  • WiredTiger использует другое представление документов на диске по сравнению с кешем в памяти, поэтому естественный порядок может меняться в зависимости от внутренних структур данных.
  • Исходный механизм хранения MMAPv1 (удаленный в MongoDB 4.2) выделяет место для записи для документов на основе правил заполнения. Если документ превышает текущее выделенное пространство для записи, это повлияет на расположение документа (и естественный порядок). Новые документы также могут быть вставлены в хранилище, отмеченное как доступное для повторного использования из-за удаленных или перемещенных документов.
  • Репликация использует идемпотентный формат журнала операций для согласованного применения операций записи для всех членов набора реплик. Каждый член набора реплик поддерживает локальные файлы данных, которые могут меняться в естественном порядке, но будут иметь тот же результат данных при применении обновлений журнала операций.

Что делать, если используется индекс?

Если используется индекс, документы будут возвращены в том порядке, в котором они были найдены (который обязательно соответствует порядку вставки или порядку ввода-вывода). Если используется более одного индекса, то порядок зависит от внутреннего индекса, который первым идентифицировал документ в процессе дедупликации.

Если вам нужен предсказуемый порядок сортировки, вы должны включить явное выражение в sort()свой запрос и иметь уникальные значения для вашего ключа сортировки.

Как ограниченные коллекции поддерживают порядок размещения?

Исключение реализации, отмеченное для естественного порядка в ограниченных коллекциях, обусловлено их особыми ограничениями использования: документы хранятся в порядке вставки, но существующий размер документа не может быть увеличен, а документы не могут быть удалены явно. Упорядочивание - это часть дизайна закрытой коллекции, которая гарантирует, что самые старые документы «устареют» первыми.

Стенни
источник
4
Значит ли это, что если я запустил одну и ту же команду find: db.collection.find ({"x": y}). Skip (20000) .limit (1000) в два разных момента времени, я получу другой результат наборы? Что произойдет, если между двумя командами не было записи?
saurabhj
6
@saurabhj: добавлено несколько примеров, которые повлияют на естественный порядок. Если документы были перемещены / удалены, вы можете получить другие наборы результатов. Если не было никаких вставок / обновлений / удалений документов, вы должны получить тот же результат. Добавление индексов не влияет на расположение документов на диске.
Stennie
7
Следует также добавить предостережение о том, что при использовании репликации естественный порядок может варьироваться между членами набора реплик.
Stennie
Кто-нибудь знает, как заставить любой из 2 прокомментированных здесь пунктов? Мы пробовали изменять документы, но они по-прежнему возвращаются в порядке их вставки ... Мне любопытно, может ли естественный порядок отличаться от порядка вставки.
Ферран Мэйлинч
Обеспечение порядка по умолчанию (например {createdAt: -1}) необходимо для реализации оптимистичных шаблонов пользовательского интерфейса (обновления списков данных в кэше без ожидания ответа сервера после создания / обновления / удаления). В противном случае вы не сможете сопоставить оптимистичный порядок на стороне клиента и порядок ответа сервера.
Эрик Бурел,
8

Он возвращается в сохраненном порядке (порядок в файле), но не гарантируется, что они находятся во вставленном порядке. Они не сортируются по полю _id. Иногда может показаться, что он отсортирован по порядку вставки, но может измениться в другом запросе. Это ненадежно.

Парвин Гасымзаде
источник