insertMany functions
Another surprise of Lesan is the use of insertMany
while all relationships
can be embedded
correctly.
Consider the following example:
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,
});
There are two
important points in the above code
:
-
The
multiCities
input is anarray
ofpure
city
fieldobjects
. Therefore, it must have the following value:"multiCities": [ { "name": "Beirout", "abb": "BI", "population": 20000000 }, { "name": "Baalbak", "abb": "BA", "population": 850000 } ]
The beautiful thing here is that before the
addCities
function is executed, all data, includingmultiCities
, isvalidated
. This feature allows us tovalidate
thewrong
databefore
sending anycommand
to thedatabase
. -
The second point is that we explicitly set the
capital
relation in the cityrelatedRelation
tofalse
. Because we do not know whichcity
is going to be chosen as thecapital
. In general,one-to-one
relations ininsertMany
should always befalse
because they destroy the concept ofinsertMany
and cause itsrelatedRelations
to be updatedonce
for every new document that is added, which is usually wrong.
Pay attention that all changes
are sent to the database
with an aggregation
pipeline.
You can find full example here and test the insertMany
method in local computer.
bfore execut main
→ city
→ addCities
:
executing main
→ city
→ addCities
:
after execut main
→ city
→ addCities
:
Let us use insertMany
to add users
:
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,
});
In the code above, there are almost all types of relationships
that we can use in insertMany
.
-
There is a
one-to-many
relationship betweenusers
andcountries
, that is, thecountry
field receives anID
, and after finding the relevantcountry
, itspure
fields are stored in theuser
. On thecountry
side, in two multiple lists, the user is stored once with ID sorted from last to first(users
field) and once with age sorted from oldest to youngest(usersByAge
). -
Also,
users
have amany-to-many
relationship with thecities
they have lived in and receive a set of cityIDs
, and after finding thosecities
, thepure
fields of each one are stored in an array calledlivedCities
.On thecity
side, thepure
fields of the enteredusers
are stored in theusers
field for eachcity
. -
The
user
has anotherrelationship
with thecity
, which is aone-to-many
relationship. In this way, theuser
saves thecity
he likes the most in themostLovedCity
field. And on thecity
side, the list of enteredusers
is stored in the field oflovedByUser
.
bfore execut main
→ user
→ addUsers
:
executing main
→ user
→ addUsers
:
after execut main
→ user
→ addUsers
:
Pay attention that all changes
are sent to the database
with an aggregation
pipeline.
You can find full example here and test the insertMany
method in local computer.
The implementation of insertMany
for the country
is also very simple because no relationship
is needed to create the countries
, we will leave the implementation of this part of the code to you.
If you want to see a real insertMany
code, you can see the code implemented for the benchmark here.
The interesting thing is that due to the correct definition of the relationship
in Lesan, the implementation of the benchmark code with insertMany
was very simple, while this task was a bit complicated in the rest of the platforms.
Also, the time
spent for entering data in Lesan is interesting, because this time is very short due to insertMany
.