I am currently using array filters to update the nested object.
My structure is -
Category Collection -
{
name:Disease,
_id:ObjectId,
subCategory:[{
name:Hair Problems,
_id:ObjectId,
subSubCategory:[{
name: Hair Fall,
_id:ObjectId
},{
name: Dandruff,
_id:ObjectId
}]
}]
}
I want to update the subsubcategory with id 1.1.1 which I am doing by using array filters.
let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { $set: { 'subCategories.$.subSubCategories.$[j]': data } };
let option = { arrayFilters: [{ 'j._id': subSubId }], new: true };
await Categories.findOneAndUpdate(query, update, option
This code is working fine but array filters change the object id of subsubCategory. Is there any other alternative to do so without changing the ObjectId.
Thanks in advance
You can loop over the keys which you are getting as payload and put inside the $set operator.
const data = {
firstKey: "key",
secondKey: "key2",
thirdKey: "key3"
}
const object = {}
for (var key in data) {
object[`subCategories.$.subSubCategories.$[j].${key}`] = data[key]
}
let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { '$set': object };
let option = { 'arrayFilters': [{ 'j._id': subSubId }], 'new': true };
await Categories.findOneAndUpdate(query, update, option)
Problem is in $set line there you have not mentioned specific fields to be update instead subCategory.$.subSubCategory.$[j] will replace complete object element that matches the _id filter. Hence your _id field is also getting updated. You have to explicitly mention the field name after array element identifier. See example below:
Suppose you want to update name field in subSubCategories from Dandruff to new Dandruff. Then do this way:
let update = { $set: { 'subCategories.$.subSubCategories.$[j].name': "new Dandruff" } };
This will only update name field in subSubCategories array
Related
I have the following Mongoose query :
let employeeData = [];
if (employees) {
employeeData = employees.map((employee) => ({ name: employee.name }));
}
await Employee.insertMany(employeeData);
This works but adds a lot of duplicate values. I only want to insert unique values. How do i do this?
Set the name index as unique
db.employees.createIndex( { "name": 1 }, { unique: true } )
Use insertMany with the ordered:false option, which won't stop the insertion if there are duplicates
await Employee.insertMany(employeeData, { ordered : false });
I have tried to many ways , but i am stuck with a simple function in javascript, and i don't know where i need to looking for ... the problem is this:
I have a Json file like this one:
{
"blacklist": [
{
"email": "strangemail#gmail.com"
},
{
"email": "strangemail1#gmail.com"
},
{
"email": "strangemail2#gmail.com"
},
{
"email": "fianlt#gmail.com"
},
{
"email": "finalstatustest#gmail.com"
}
]
}
I would like simple remove an email with a simple function like this one:
function cancel(email) // parameter that contain the value to delete
{
let rawdata = fs.readFileSync('pvt.json'); //get local json file
let mydata = JSON.parse(rawdata); //parsing rawdata
var key = email; //setting up key
delete mydata.blacklist[key]; //using delete function for delete an element
let data = JSON.stringify(mydata, null, 2); //stringify the result
fs.writeFileSync('pvt.json', data); // overwrite local file with new one with all changes
}
the problem is ... it doesn't works ... i don't know why ... i tried to read the documentation, but i didn't found any solution 😢
The delete operator is for removing a property from an object, using the property's name. You're trying to remove an entry from an array, using the value of a property of an object in the array.
Assuming email is a variable containing the email address in the entry you want to remove, filter is one easy way to do that:
mydata.blacklist = mydata.blacklist.filter(entry => entry.email !== email);
filter builds a new array from the entries in the original array that meet the criteria in the callback — in this case, that their email property doesn't match the email address you want to remove.
If you wanted to modify the array in place rather than creating a new one, you'd use findIndex and splice:
const index = mydata.blacklist.findIndex(entry => entry.email === email);
if (index !== -1) {
mydata.blacklist.splice(index, 1); // Remove the entry at the index
}
Delete works to delete a key-value from an object. Here you have an array of items[objects]. You should use filter to remove unwanted element.
Update:
function cancel(selectedEmail) {
let rawdata = fs.readFileSync("pvt.json"); //get local json file
let mydata = JSON.parse(rawdata); //parsing rawdata
mydata.blacklist = mydata.blacklist.filter(
(item) => item.email !== selectedEmail.email
);
fs.writeFileSync("pvt.json", JSON.stringify(mydata, null, 2)); // overwrite local file with new one with all changes
}
Sample:
const info = {
blacklist: [
{
email: "strangemail#gmail.com",
},
{
email: "strangemail1#gmail.com",
},
{
email: "strangemail2#gmail.com",
},
{
email: "fianlt#gmail.com",
},
{
email: "finalstatustest#gmail.com",
},
],
};
const selectedEmail = {email: "finalstatustest#gmail.com"}
info.blacklist = info.blacklist.filter(item => item.email !== selectedEmail.email)
console.log(info)
How can I retrieve the data from a data object in Vue?
I have data in this format:
datasets: [{
text:"Cars",
value: "[1,2,3]"
},
{
text:"Trains",
value: "[1,4,10]
}
]
Now I from route props I get the following info:
this.selectedText= this.$route.name;
Where this.$route.name is "Cars" for example.
Now I want to take this use this.selectedValue to get corresponding Value from this array:
so if this.selectedText="Cars" then this.selectedValue=[1,2,3] or based on this I want to retrieve the value of given text.
Create a method and use this code to find out the matching one.
function setSelectedValue() {
let matchingDatSet = this.datasets.find(ele => ele.text == this.selectedText);
if(matchingDataSet !== undefined) {
this.selectedValue = matchingDataSet.value;
}
}
I have an Object on sessionStorage for which I need to update values on user input. I am able to update at the root of the Object but not the values that are nested on a deeper level.
request('http://localhost:7474/graphql/', query).then(data => {...}
sessionStorage.setItem('queryData', JSON.stringify(data));
function update(value){
let prevData = JSON.parse(sessionStorage.getItem('queryData'));
Object.keys(value).forEach(function(val, key){
prevData[val] = value[val];
});
sessionStorage.setItem('queryData', JSON.stringify(prevData));
}
update({ maritalStatus: "single" });
So maritalStatus ends up been added and not replaced and I must replace the value:
Object: [,...]
0: {id: "x", maritalStatus: "married"} //want to replace this value here
maritalStatus: "single" // this is where the value is been written
Your data in storage is an Array. So the way you are updating it like prevData[val] = value[val]; is adding another property to the array with index of maritalStatus and value of "single". The object at index 0 is untouched.
My suggested fix is to also include the id in your update call. Then loop through the array in storage and look for the object with the matching id.
Once the id matches update that object, or log if no id matches are found.
let dataInStorage = [{
id: "x",
maritalStatus: "married"
}];
function update(updateObj) {
let prevData = dataInStorage;
let id = updateObj.id;
dataInStorage.forEach(function(data) {
if (data.id === id) {
Object.keys(updateObj).forEach(function(key, index) {
data[key] = updateObj[key];
});
} else {
console.log(`did not find object with id: ${id}`);
}
});
console.log(prevData)
//sessionStorage.setItem('queryData', JSON.stringify(prevData));
}
update({
id: "x",
maritalStatus: "single"
});
I need to find nested objects in MongoDb using the Node.js Driver.
I'm having trouble accessing nested properties when the property name is dynamic. Here's my code:
//This gives expected results but "name1" isn't dynamic
collection.find({ 'followers.name1': { $exists: false } })
//Here's what I tried that does not give expected results
const username = "name1"
let query = { followers: {} }
query.followers[username] = { $exists: false }
collection.find(query)
Here's an example of the database structure:
{
"_id":"xxxxxxxxxxx",
"dateAdded":"2017-09-20T08:36:40.325Z",
"followers":{
"name1":{
"followedOn":"2017-09-20T08:36:40.325Z",
"unfollowedOn":null
},
"name2":{
"followedOn":"2017-09-20T08:36:40.325Z",
"unfollowedOn":null
}
}
}
Edit: my question is not a duplicate of the one marked as a duplicate. MongoDb find() argument is not an object literal. That's the whole point of my question, using like it like an object literal doesn't work.
I found the solution myself in the end. The key needs to be a string so you need to do:
const username = 'name1'
let query = {}
query['followers.'+username] = { $exists: false }
collection.find(query)