MongoDB ObjectID生成疑问:仅计数器变化及跨模型共享原因
关于Mongoose生成ObjectID的两个疑问
根据MongoDB官方文档,ObjectID是一个96位数字,由以下部分构成:
- 4字节时间戳,代表自Unix纪元以来的秒数(可用至2106年)
- 5字节随机值
- 3字节自增计数器,初始值为随机数
疑问1:批量生成ObjectID时仅计数器部分变化
执行以下代码生成1000个ObjectID:
const mongoose = require('mongoose'); const carSchema = new mongoose.Schema({ driver: mongoose.ObjectId }); const Car = mongoose.model('Car', carSchema); const car = new Car(); let i = 0; while (i < 1000) { car.driver = new mongoose.Types.ObjectId(); console.log(car.driver.toString()); i++; }
预期会看到三部分均有变化,但实际仅计数器部分递增:
~/tmp$ head t2 638f7d3f37664dec556b0491 638f7d3f37664dec556b0492 638f7d3f37664dec556b0493 638f7d3f37664dec556b0494 638f7d3f37664dec556b0495 638f7d3f37664dec556b0496 638f7d3f37664dec556b0497 638f7d3f37664dec556b0498 638f7d3f37664dec556b0499 638f7d3f37664dec556b049a ~/tmp$ tail t2 638f7d3f37664dec556b086f 638f7d3f37664dec556b0870 638f7d3f37664dec556b0871 638f7d3f37664dec556b0872 638f7d3f37664dec556b0873 638f7d3f37664dec556b0874 638f7d3f37664dec556b0875 638f7d3f37664dec556b0876 638f7d3f37664dec556b0877 638f7d3f37664dec556b0878
请问为何不会出现三部分均变化的情况?
疑问2:不同模型生成ObjectID共享同一计数器
执行以下代码:
const mongoose = require('mongoose'); const carSchema = new mongoose.Schema({ driver: mongoose.ObjectId }); const carSchema2 = new mongoose.Schema({ driver: mongoose.ObjectId }); const Car = mongoose.model('Car', carSchema); const Car2 = mongoose.model('Car2', carSchema2); const car = new Car(); const car2 = new Car2(); const splitElements = id => { return { seconds: parseInt(id.slice(0, 8), 16), random: parseInt(id.slice(8, 18), 16), counter: parseInt(id.slice(18, 24), 16), }; }; const sleep = ms => { return new Promise(resolve => setTimeout(resolve, ms)); }; (async () => { let i = 0; while (i < 5) { car.driver = new mongoose.Types.ObjectId(); console.log(car.driver.toString(), JSON.stringify(splitElements(car.driver.toString()))); await sleep(100); i++; } })(); (async () => { let i = 0; while (i < 5) { car2.driver = new mongoose.Types.ObjectId(); console.log(car2.driver.toString(), JSON.stringify(splitElements(car2.driver.toString()))); await sleep(100); i++; } })();
输出结果显示计数器从第一个模型的结束值继续递增:
638fe308b0a1fb8a3c22e2e9 {"seconds":1670374152,"random":758631860796,"counter":2286313} 638fe308b0a1fb8a3c22e2ea {"seconds":1670374152,"random":758631860796,"counter":2286314} 638fe308b0a1fb8a3c22e2eb {"seconds":1670374152,"random":758631860796,"counter":2286315} 638fe308b0a1fb8a3c22e2ec {"seconds":1670374152,"random":758631860796,"counter":2286316} 638fe308b0a1fb8a3c22e2ed {"seconds":1670374152,"random":758631860796,"counter":2286317} 638fe308b0a1fb8a3c22e2ee {"seconds":1670374152,"random":758631860796,"counter":2286318} 638fe308b0a1fb8a3c22e2ef {"seconds":1670374152,"random":758631860796,"counter":2286319} 638fe308b0a1fb8a3c22e2f0 {"seconds":1670374152,"random":758631860796,"counter":2286320} 638fe308b0a1fb8a3c22e2f1 {"seconds":1670374152,"random":758631860796,"counter":2286321} 638fe308b0a1fb8a3c22e2f2 {"seconds":1670374152,"random":758631860796,"counter":2286322}
原本预期每个模型对象拥有独立计数器,为何它们会共享同一计数器?
内容的提问来源于stack exchange,提问作者Sandra Schlichting
相关产品推荐
相关产品推荐

