deleteOne functions
Deletion
has the same problems as update
.
Delete a User
Pay attention to the following code:
const deleteUserValidator = () => {
return object({
set: object({
_id: string(),
}),
get: object({
success: optional(enums([0, 1])),
}),
});
};
const deleteUser: ActFn = async (body) => {
const {
set: { _id },
get,
} = body.details;
return await users.deleteOne({
filter: { _id: new ObjectId(_id) },
});
};
coreApp.acts.setAct({
schema: "user",
actName: "deleteUser",
validator: deleteUserValidator(),
fn: deleteUser,
});
If you remember, when we defined a relationship for the user, we gave it the following object as a relationship:
{
livedCities: {
optional: false,
schemaName: "city",
type: "multiple",
sort: {
field: "_id",
order: "desc",
},
relatedRelations: {
users: {
type: "multiple",
limit: 50,
sort: {
field: "_id",
order: "desc",
},
},
},
},
country: {
optional: false,
schemaName: "country",
type: "single",
relatedRelations: {
users: {
type: "multiple",
limit: 50,
sort: {
field: "_id",
order: "desc",
},
},
},
},
}
Fortunately, all the relationships that exist for the user are the ones we have defined above, and there is no relatedRelation
for the user
.
That's why we said fortunately, because if a document has relatedRelations
, by deleting
that document, some documents
may be meaningless or not used. For example, if we want to delete a country
in the example we have completed so far, the cities
belonging to that country will become meaningless data.
There is no problem for users
and we can simply use delete
without other data being unused. But by deleting
each user
, we have to check its mainRelations
and if the user
is stored as an embed
, delete
the user
there, and if another user
needs to be added to the embed
list, add the other user
as well.
In our example, we have to check the embedded
list of users
in the cities
where the user lives, as well as the list of users
in the country
belonging to that user.
You can find full example here and test the deleteOne
method in local computer.
bfore execut main
→ user
→ deleteUser
:
executing main
→ user
→ deleteUser
:
after execut main
→ user
→ deleteUser
:
Add E2E Test
For adding deleteUser
request to E2E section you should click on the e2e button (like bottom picture) to add your request to E2E section.
Then, in the E2E section and deleteUser
sequence, you should replace the user id that you set capture in own sequence with default user id. default user id in deleteUser
sequence is like below picture.
The replaced country id is like below picture.
Delete a Country
What if we want to remove a country
?
Although we have not defined any relationship
for the country
, both the city
and the user
have created relationships
with the country
.
const countryRelations = {};
const cityRelations = {
country: {
optional: false,
schemaName: "country",
type: "single" as RelationDataType,
relatedRelations: {
cities: {
type: "multiple" as RelationDataType,
limit: 50,
sort: {
field: "_id",
order: "desc" as RelationSortOrderType,
},
},
citiesByPopulation: {
type: "multiple" as RelationDataType,
limit: 50,
sort: {
field: "population",
order: "desc" as RelationSortOrderType,
},
},
capital: {
type: "single" as RelationDataType,
},
},
},
};
const userRelations = {
livedCities: {
optional: false,
schemaName: "city",
type: "multiple",
sort: {
field: "_id",
order: "desc",
},
relatedRelations: {
users: {
type: "multiple",
limit: 50,
sort: {
field: "_id",
order: "desc",
},
},
},
},
country: {
optional: false,
schemaName: "country",
type: "single",
relatedRelations: {
users: {
type: "multiple",
limit: 50,
sort: {
field: "_id",
order: "desc",
},
},
},
},
};
As we said earlier, the data created based on this country
will be useless. Here the cities
and users
created based on this country
become useless.
Pay attention to the following code:
const deleteCountryValidator = () => {
return object({
set: object({
_id: string(),
}),
get: object({
success: optional(enums([0, 1])),
}),
});
};
const deleteCountry: ActFn = async (body) => {
const {
set: { _id },
get,
} = body.details;
return await countries.deleteOne({
filter: { _id: new ObjectId(_id) },
});
};
coreApp.acts.setAct({
schema: "country",
actName: "deleteCountry",
validator: deleteCountryValidator(),
fn: deleteCountry,
});
By adding the above code
and running the software and sending a request
to delete
a country
, and finally if that country has a city
or user
, we will encounter the following error
:
{
body: {
message: please clear below relations status before deletion: [ { schemaName: country, type: single, optional: false, fieldName: country, collection: city, doc: { _id: 65a3d213e18957d8c176ffb4, name: Hamedan, population: 900000, abb: HM, country: { _id: 65a3d213e18957d8c176ffb2, name: Islamic Republic Of Iran, population: 89000000, abb: IR }, users: [ { _id: 65a3d213e18957d8c176ffc0, name: Mohammad Sheida, age: 20 }, { _id: 65a3d213e18957d8c176ffbf, name: Elham Afshar, age: 25 }, { _id: 65a3d213e18957d8c176ffbd, name: Saeid Ghal, age: 27 }, { _id: 65a3d213e18957d8c176ffbc, name: Ehsan Akefi, age: 20 }, { _id: 65a3d213e18957d8c176ffbb, name: Amir Meyari, age: 30 } ] } }, { schemaName: country, type: single, optional: false, fieldName: country, collection: user, doc: { _id: 65a3d213e18957d8c176ffb7, name: Syd Amir, age: 36, livedCities: [ { _id: 65a3d213e18957d8c176ffb4, name: Hamedan, population: 900000, abb: HM }, { _id: 65a3d213e18957d8c176ffb5, name: Tehran, population: 1000000, abb: TH } ], country: { _id: 65a3d213e18957d8c176ffb2, name: Islamic Republic Of Iran, population: 89000000, abb: IR } } }]
},
success: false
}
We have two ways:
Delete
all these documentsrelated
to thiscountry
one by one.- Set the
hardCascade
option totrue
in thedeleteOne
function. We change the above code as follows:
return await countries.deleteOne({
filter: { _id: new ObjectId(_id) },
hardCascade: true,
});
This will cause all the dependent documents and the dependent documents of these dependent documents to be deleted
recursively.
You can find full example here and test the deleteOne
method in local computer.
bfore execut main
→ country
→ deleteCountry
:
executing main
→ country
→ deleteCountry
:
after execut main
→ country
→ deleteCountry
:
Add E2E Test
Like before, for adding deleteCountry
request to E2E section you should click on the e2e button (like bottom picture) to add your request to E2E section.
Then, in the E2E section and deleteCountry
sequence, you should replace the country id that you set capture in own sequence with default country id. default country id in deleteCountry
sequence is like below picture.
The replaced country id is like below picture.