Skip to content

Commit aef1993

Browse files
committed
perf(NODE-6466): make _id appear first in document
1 parent 5c4355a commit aef1993

File tree

1 file changed

+208
-1
lines changed

1 file changed

+208
-1
lines changed

test/integration/crud/crud.prose.test.ts

+208-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
type MongoClient,
1212
MongoClientBulkWriteError,
1313
MongoInvalidArgumentError,
14-
MongoServerError
14+
MongoServerError,
15+
type PkFactory
1516
} from '../../mongodb';
1617
import { filterForCommands } from '../shared';
1718

@@ -1166,4 +1167,210 @@ describe('CRUD Prose Spec Tests', () => {
11661167
}
11671168
});
11681169
});
1170+
1171+
describe('16. Generated document identifiers are the first field in their document', function () {
1172+
// Test that the driver generates document identifiers as the first field in their document.
1173+
// use the command started event to check for first key of document
1174+
// repeat for insertOne, insertMany, updateOne, updateMany, replaceOne, legacy bulkWrite and client bulkWrite.
1175+
1176+
let client: MongoClient;
1177+
const commands: CommandStartedEvent[] = [];
1178+
let collection: Collection<{ _id?: number; name: string; age?: number }>;
1179+
1180+
beforeEach(async function () {
1181+
client = this.configuration.newClient({}, { monitorCommands: true });
1182+
await client.connect();
1183+
1184+
await client.db('identifier-test').dropDatabase();
1185+
collection = await client.db('identifier-test').createCollection('collection', {
1186+
pkFactory: {
1187+
incrementingId: 1,
1188+
createPk() {
1189+
return this.incrementingId++;
1190+
}
1191+
} as PkFactory
1192+
});
1193+
commands.length = 0;
1194+
1195+
client.on('commandStarted', (event: CommandStartedEvent) => commands.push(event));
1196+
});
1197+
1198+
afterEach(async function () {
1199+
commands.length = 0;
1200+
await client.close();
1201+
});
1202+
1203+
describe('when the driver generates the _id', function () {
1204+
describe('insertOne', function () {
1205+
it('generates _id as the first field', async function () {
1206+
await collection.insertOne({ name: 'john doe' });
1207+
1208+
const [{ command }] = commands;
1209+
expect(command).to.have.nested.property('documents[0]._id');
1210+
expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
1211+
});
1212+
});
1213+
1214+
describe('insertMany', function () {
1215+
it('generates _id as the first field', async function () {
1216+
await collection.insertMany([{ name: 'john doe' }, { name: 'jane doe' }]);
1217+
1218+
const [{ command }] = commands;
1219+
expect(command).to.have.nested.property('documents[0]._id');
1220+
expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
1221+
expect(command).to.have.nested.property('documents[1]._id');
1222+
expect(Object.keys(command.documents[1])).to.have.property('0', '_id');
1223+
});
1224+
});
1225+
1226+
describe('legacy bulkWrite', function () {
1227+
it('generates _id as the first field in documents', async function () {
1228+
await collection.bulkWrite([
1229+
{ insertOne: { document: { name: 'john doe' } } },
1230+
{ insertOne: { document: { name: 'jane doe' } } }
1231+
]);
1232+
1233+
const [{ command }] = commands;
1234+
expect(command).to.have.nested.property('documents[0]._id');
1235+
expect(Object.keys(command.documents[0])).to.have.property('0', '_id');
1236+
expect(command).to.have.nested.property('documents[1]._id');
1237+
expect(Object.keys(command.documents[1])).to.have.property('0', '_id');
1238+
});
1239+
});
1240+
1241+
describe('client bulkWrite', function () {
1242+
it('generates _id as the first field in documents', async function () {
1243+
await client.bulkWrite<{ 'identifier-test.collection': { _id: number; name: string } }>([
1244+
{
1245+
name: 'insertOne',
1246+
namespace: 'identifier-test.collection',
1247+
document: { name: 'john doe' }
1248+
},
1249+
{
1250+
name: 'insertOne',
1251+
namespace: 'identifier-test.collection',
1252+
document: { name: 'jane doe' }
1253+
}
1254+
]);
1255+
1256+
const [{ command }] = commands;
1257+
expect(command).to.have.nested.property('ops[0].document._id');
1258+
expect(Object.keys(command.ops[0].document)).to.have.property('0', '_id');
1259+
expect(command).to.have.nested.property('ops[1].document._id');
1260+
expect(Object.keys(command.ops[1].document)).to.have.property('0', '_id');
1261+
});
1262+
});
1263+
});
1264+
1265+
describe('when the user provides the _id', function () {
1266+
describe('insertOne', function () {
1267+
it('keeps _id in its original position', async function () {
1268+
await collection.insertOne({ name: 'john doe', _id: 1 });
1269+
1270+
const [{ command }] = commands;
1271+
expect(command).to.have.nested.property('documents[0]._id');
1272+
expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
1273+
});
1274+
});
1275+
1276+
describe('insertMany', function () {
1277+
it('keeps _id in its original position', async function () {
1278+
await collection.insertMany([
1279+
{ name: 'john doe', _id: 1 },
1280+
{ name: 'jane doe', _id: 2 }
1281+
]);
1282+
1283+
const [{ command }] = commands;
1284+
expect(command).to.have.nested.property('documents[0]._id');
1285+
expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
1286+
expect(command).to.have.nested.property('documents[1]._id');
1287+
expect(Object.keys(command.documents[1])).to.have.property('1', '_id');
1288+
});
1289+
});
1290+
1291+
describe('updateOne', function () {
1292+
it('keeps _id in its original position in upserted document', async function () {
1293+
await collection.updateOne({ name: 'john doe', _id: 1 }, { $set: {} }, { upsert: true });
1294+
1295+
const [{ command }] = commands;
1296+
expect(command).to.have.nested.property('updates[0].q._id');
1297+
expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
1298+
});
1299+
});
1300+
1301+
describe('updateMany', function () {
1302+
it('keeps _id in its original position in upserted documents', async function () {
1303+
await collection.updateMany({ name: 'john doe', _id: 1 }, { $set: {} }, { upsert: true });
1304+
1305+
const [{ command }] = commands;
1306+
expect(command).to.have.nested.property('updates[0].q._id');
1307+
expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
1308+
});
1309+
});
1310+
1311+
describe('replaceOne', function () {
1312+
it('keeps _id in its original position in filter document', async function () {
1313+
await collection.replaceOne(
1314+
{ name: 'john doe', _id: 1 },
1315+
{ name: 'john doe', age: 30 },
1316+
{ upsert: true }
1317+
);
1318+
1319+
const [{ command }] = commands;
1320+
expect(command).to.have.nested.property('updates[0].q._id');
1321+
expect(Object.keys(command.updates[0].q)).to.have.property('1', '_id');
1322+
});
1323+
1324+
it('keeps _id in its original position in replacement document', async function () {
1325+
await collection.replaceOne(
1326+
{ name: 'john doe' },
1327+
{ name: 'john doe', age: 30, _id: 1 },
1328+
{ upsert: true }
1329+
);
1330+
1331+
const [{ command }] = commands;
1332+
expect(command).to.have.nested.property('updates[0].u._id');
1333+
expect(Object.keys(command.updates[0].u)).to.have.property('2', '_id');
1334+
});
1335+
});
1336+
1337+
describe('legacy bulkWrite', function () {
1338+
it('keeps _id in its original position in documents', async function () {
1339+
await collection.bulkWrite([
1340+
{ insertOne: { document: { name: 'john doe', _id: 1 } } },
1341+
{ insertOne: { document: { name: 'jane doe', _id: 2 } } }
1342+
]);
1343+
1344+
const [{ command }] = commands;
1345+
expect(command).to.have.nested.property('documents[0]._id');
1346+
expect(Object.keys(command.documents[0])).to.have.property('1', '_id');
1347+
expect(command).to.have.nested.property('documents[1]._id');
1348+
expect(Object.keys(command.documents[1])).to.have.property('1', '_id');
1349+
});
1350+
});
1351+
1352+
describe('client bulkWrite', function () {
1353+
it('keeps _id in its original position in documents', async function () {
1354+
await client.bulkWrite<{ 'identifier-test.collection': { _id: number; name: string } }>([
1355+
{
1356+
name: 'insertOne',
1357+
namespace: 'identifier-test.collection',
1358+
document: { name: 'john doe', _id: 1 }
1359+
},
1360+
{
1361+
name: 'insertOne',
1362+
namespace: 'identifier-test.collection',
1363+
document: { name: 'jane doe', _id: 2 }
1364+
}
1365+
]);
1366+
1367+
const [{ command }] = commands;
1368+
expect(command).to.have.nested.property('ops[0].document._id');
1369+
expect(Object.keys(command.ops[0].document)).to.have.property('1', '_id');
1370+
expect(command).to.have.nested.property('ops[1].document._id');
1371+
expect(Object.keys(command.ops[1].document)).to.have.property('1', '_id');
1372+
});
1373+
});
1374+
});
1375+
});
11691376
});

0 commit comments

Comments
 (0)