insertMany
Another Lesan surprise: insertMany keeps all relationships embedded correctly while inserting many documents at once. It's fast โ changes go to the database as a single aggregation pipeline.
Insert many citiesโ
const addCitiesValidator = () => {
return object({
set: object({
multiCities: array(object(countryCityPure)),
country: objectIdValidation,
}),
get: coreApp.schemas.selectStruct("city", 1),
});
};
const addCities: ActFn = async (body) => {
const { country, multiCities } = body.details.set;
return await cities.insertMany({
docs: multiCities,
projection: body.details.get,
relations: {
country: {
_ids: new ObjectId(country),
relatedRelations: {
cities: true,
citiesByPopulation: true,
capital: false,
},
},
},
});
};
coreApp.acts.setAct({
schema: "city",
actName: "addCities",
validator: addCitiesValidator(),
fn: addCities,
});
Two important points:
-
Validation happens before any database command.
multiCitiesis an array of pure city objects, and the whole payload โ including each city's fields โ is validated up front:"multiCities": [{ "name": "Beirout", "abb": "BI", "population": 20000000 },{ "name": "Baalbak", "abb": "BA", "population": 850000 }]Wrong data is rejected before anything reaches Mongo.
-
Single relations must be
false. We explicitly setcapital: falsebecause we don't know which city will become the capital. In general, one-to-one relations ininsertManyshould always befalseโ if they weretrue, the related relation would be updated once for every new document, which is usually wrong.
insertMany accepts the same shape as insertOne, but docs is an array:
docsโ an array of pure-field objects.relationsโ the relation input (same asinsertOne).projectionโ shapes the written data.options(optional) โ MongoDBBulkWriteOptions.
The full example is examples/document/10-1-insertMany.ts.
Before running addCities:
While running:
After running โ both cities are in the collection, embedded in the country's lists:
Insert many users โ all relation types at onceโ
The next example exercises almost every relation shape in one insertMany:
const addUsersValidator = () => {
return object({
set: object({
multiUsers: array(object()),
country: objectIdValidation,
livedCities: array(objectIdValidation),
lovedCity: objectIdValidation,
}),
get: coreApp.schemas.selectStruct("user", 1),
});
};
const addUsers: ActFn = async (body) => {
const { country, multiUsers, livedCities, lovedCity } = body.details.set;
const obIdLivedCities = livedCities.map((lp: string) => new ObjectId(lp));
return await users.insertMany({
docs: multiUsers,
projection: body.details.get,
relations: {
country: {
_ids: new ObjectId(country),
relatedRelations: {
users: true,
},
},
livedCities: {
_ids: obIdLivedCities,
relatedRelations: {
users: true,
},
},
mostLovedCity: {
_ids: new ObjectId(lovedCity),
relatedRelations: {
lovedByUser: true,
},
},
},
});
};
coreApp.acts.setAct({
schema: "user",
actName: "addUsers",
validator: addUsersValidator(),
fn: addUsers,
});
Here all the relation types appear together:
- one-to-many โ
country: the users store the country's pure fields; on the country side the users are stored in theuserslist. - many-to-many โ
livedCities: an array of city ids; each user stores those cities' pure fields inlivedCities, and each city stores the users in itsuserslist. - one-to-many (single) โ
mostLovedCity: a single city id stored in each user, while the city keeps the users inlovedByUser.
The full example is examples/document/10-2-insertMany.ts.
Before running addUsers:
While running:
After running โ all users inserted, with every relation embedded on both sides:
Insert many countriesโ
Inserting countries needs no relations argument at all, since country has none โ the implementation is left to you. A real-world example lives in the benchmark.
The interesting takeaway: because relations are defined once and embedded automatically, the benchmark's insertMany implementation was trivial โ and the insert time is remarkably short.
Next stepsโ
- Back to the API Reference for the full ODM surface
- See the whole country/city/user example come together in relations-in-depth