Reputation: 3434
Now this is something that I already have managed to implement, I am just wondering if there is an easier/better way to do it as I am just starting to work with Mongoose and MongoDB.
Lets say that I have a couple of documents within a collection that have Name fields (I hope I got the terminology right), like this: [{Name: "Name1"}, {Name: "Name3"}]
, lets call it NamesConfiguration
.
Now I also have a configuration array config
with names: ["Name1", "Name2"]
.
My objective is to remove all names from NamesConfiguration
that do not exist in the config
array, and then add all names from the config
array that do not exist in the NamesConfiguration
, so my final collection should be [{Name: "Name1"}, {Name: "Name2"}]
.
try {
const config = ["Name1", "Name2"];
const NamesConfiguration = await UIConfiguration.find(); // getting all available nameconfigs from the db
NamesConfiguration.forEach(async (nameConfig) => {
if (!config.includes(nameConfig.Name)) { // loop through and delete the ones that are not within the array
console.log("deleting" + nameConfig.Name);
await UIConfiguration.findOneAndDelete({ Name: nameConfig.Name });
}
});
// loop through the array and see if the names are present
config.forEach(async (configName) => {
let found = NamesConfiguration.find((nameConfig) => nameConfig.Name === configName);
// create new nameconfig if not found
if (!found) {
console.log("Creating" + configName);
let NameConfigToAdd = new UIConfiguration({
Name: configName
});
await NameConfigToAdd.save();
}
});
} catch (e) {
console.log(e);
}
I just want to know if there is a better, "more proper" way of doing that operation. In my case even if this can potentially impact performance it will nto be an issue at all, since I will never have more than 10-20 entries.
Solved it by following Yousaf's answer:
const availableConfigs = (await UIConfiguration.find()).map(
(availableConfig) => {
return availableConfig.Name;
}
);
const configNamesToAdd = robotsNames
.filter((robotName) => !availableConfigs.includes(robotName))
.map((configName) => {
return {
Name: configName
};
});
const deleteCondition = {
Name: { $not: { $in: robotsNames } },
};
await UIConfiguration.deleteMany(deleteCondition);
await UIConfiguration.insertMany(configNamesToAdd);
Upvotes: 1
Views: 1017
Reputation: 29314
You can do it in following steps:
Delete all the documents in the collection whose Name
field's value is present in the config
array.
To delete any document whose Name
field's value is not in the config
array, write a delete query using $in
and $not
operators.
UIConfiguration.deleteMany({ Name: { $not: { $in: ["Name1", "Name2"] } } });
Fetch all the documents whose Name
field's value exists in the config
array. You can do this using $in
operator
UIConfiguration.find({ Name: { $in: ["Name1", "Name2"] } });
Iterate over the returned array of documents and filter out those name strings in config
array that do not match any document's Name
field value.
Finally, insert all the names in the filtered array in the collection using .insertMany
method
UIConfiguration.insertMany([/* filtered name objects */]);
For further details on methods and operators used above, see:
Upvotes: 2