Короткая версия: да, за исключением редких ситуаций
Mongo _ids имеют "4-байтовое значение, представляющее секунды с начала эпохи Unix, 5-байтовое случайное значениеи 3-байтовый счетчик, начиная со случайного значения. " Каждая из этих частей будет обычно (но не всегда) упорядочена (метка времени и счетчик) или постоянна (5-байтовое случайное значение).
По умолчанию драйверы базы данных mongo будут генерировать _id
с, поэтому вы можете положиться на те _id
с одинаковым случайным значением и, как правило, полагаться на метку времени и счетчик, перемещающийся вперед.https://docs.mongodb.com/manual/core/document/
4-байтовая временная метка
Если вы посмотрите на код генерации ObjectId для узла , вы увидите, что он использует Date
для генерацииначальная часть метки времени ObjectId & Date
может возвращаться назад при обновлении часов.Я бы предположил, что он действует одинаково на всех драйверах, поэтому у них, скорее всего, будут неправильные _ids, если вы делаете вставку в то же время, когда обновляются часы.
По результатам тестирования кажется, что даже если вы принудительно сгенерировали идентификаторы , insertMany
с ordered=false
на сервере (то есть базе данных), все равно сохраните порядок _id.Mongo не выполняет размазывание обновлений часов, поэтому, если на сервере, на котором запущен Mongo, есть обновления часов, _ids также может быть не в порядке в массиве вставок.
The 5случайное значение байта
Это должно оставаться постоянным, но если у вас есть монго (а не драйвер), сгенерируйте _ids и есть сбой, я думаю, что это изменится.Я не уверен, как это будет взаимодействовать со вставками.
3-байтовый счетчик
3-байтовый счетчик будет сброшен после подсчета 2 ^ 24 (~ 16 миллионов) документов.Это означает, что если ваш драйвер (если _ids генерируется там) или mongo (если _ids генерируется там) достигает этой точки, документы, вставленные в течение этой секунды в массовой вставке (упорядоченные или неупорядоченные), не будут упорядочены_id.
Mongo's recordId
Внутренне mongo использует recordId
вместо _id в качестве первичного ключа.Если вы делаете неупорядоченную вставку и смотрите на recordIds
, _ids
будет в том порядке, в котором они были в массиве вставок, но recordIds
будет упорядочен в том порядке, в котором они фактически были вставлены, и не будетсоответствовать порядку _id.
const conn = await mongodb.connect("mongodb://mongo:27017/");
const db = conn.db("test");
await db.collection("test").remove({});
const toInsert = [];
for (let i = 0; i < 100; i++) {
toInsert.push({i})
}
await db.collection("test").insertMany(toInsert, {ordered: false, forceServerObjectId: true});
const results = await db.collection("test").find({}).showRecordId(true).sort({_id: 1}).toArray();
let prev;
for (const result of results) {
if (prev) {
// this will throw because recordids are not ordered as expected
assert(prev < result.$recordId)
}
prev = result.$recordId;
}