update nested array data in mongodb and node js - javascript

I want to update status in corder data. i try many time but i cannot update that data. if you know how update that data ??
{
"_id": "63064232cf92b07e37090e0a",
"sname": "Bombay collection ",
"name": "Hussain Khan",
"costomer": [
{
"cname": "Basan",
"cphone": 9863521480,
"_id": "632eeff2a9b88eb59d0210f0",
"corder": [
{
"clothType": "Shirt",
"date": "2022-10-21",
"status": "false",
"_id": "635283363edde6a0e9e92dc0"
},
]
}
]
}

You can use $[<identifier>]. For example:
db.collection.update(
{},
{$set: {"costomer.$[elemA].corder.$[elemB].status": newStatus}},
{arrayFilters: [
{"elemA._id": costomerId},
{"elemB._id": corderId}
]}
)
See how it works on the playground example

Related

How to remove deeply nested object (Node.js, mongoose)

I'm making a kanban task management app and I'm trying to remove a task with the _id: req.params.id which has the value of 62fa5ae05778ec97bc6ee23a. I tried the following:
const task = await Board.findOneAndUpdate(
{
"columns.tasks._id": req.params.id,
},
{ $pull: { "columns.$.tasks.$._id": req.params.id } },
{ new: true }
);
But I get the error Too many positional (i.e. '$') elements found in path'columns.$.tasks.$._id'
I searched for a while and came across arrayFilters from the docs but I'm struggling a lot to understand how to implement it for this particular need.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{
"title": "Task Four",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23b"
},
{
"name": "do homework",
"completed": false,
"_id": "62fa5ae05778ec97bc6ee23c"
}
],
"_id": "62fa5ae05778ec97bc6ee23a"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v": 0
}
You need to use $[] positional operator in order to pull from the nested array. Try running this query:
db.Board.updateOne({
"_id" : "62fa5aa25778ec97bc6ee231",
}, {
$pull: { 'columns.$[].tasks': { '_id': '62fa5ae05778ec97bc6ee23a' } }
});

How to query for an object within an array in mongoose

I'm new to mongoose and I'm having trouble querying for specific objects within an array.
My data model looks like this:
{
"users": [
{
"_id": "61b0d6637e169ddebf72c18a",
"name": "Brian Test",
"email": "briantest#gmail.com",
"password": "xxx",
"accountType": "type1",
"__v": 0,
"title": "title1",
"about": "about1",
"education": [
{
"recordId": 1,
"institution": "institution1",
"title": "title1"
},
{
"recordId": 2,
"institution": "institution2",
"title": "title2"
},
{
"recordId": 3,
"institution": "institution3",
"title": "title3"
}
]
}
]
}
The query I need is to perform a crud on education records. For it I'll have the user ID and the education record ID.
I'm not sure how to nest the education record query within the user query.
I've tried something like this but It's not working.
let user = await User.findOne({_id: req.user.user.id})
let recordToUpdate = await user.education.findOne({recordId: req.body.recordId})
console.log(recordToUpdate)
I'll appreciate if you could give examples for reading, updating and deleting records aswell.
Thanks!

Within an array, remove an item from an array within each object that item appears in

My mongodb document(table) 'Org_unit' looks like this:
{
"_id": ObjectId("0894f016e6e2e073c19e051")
"allowedusers": [
"admin",
"Fred",
"Bob",
"Layneh"
],
"name": "News management",
"divisions": [
{
"allowedusers": [
"admin",
"Larry",
"Bob",
"Harry",
"Fred"
],
"_id": ObjectId("60894f016e6e2e073c19e052"),
"name": "Finances",
"credentials": [
{
"_id": ObjectId("94f0944f016e6e2e2342cc"),
"name": "FNB - FA",
"userName": "example#email.com",
"password": "examplePassword!##"
}
]
},
{
"allowedusers": [
"admin",
"Larry",
"Bob",
"Harry",
"Fred"
],
"_id": ObjectId("60894f016e6e2e073c19e052"),
"name": "Development",
"credentials": [
{
"_id": ObjectId("94f0944f016e6e2e2342cc"),
"name": "FNB - DEV",
"userName": "example#email.com",
"password": "examplePassword!##"
}
]
}
],
"__v": 11
}
This is my fist post here, hello! Ok so I have been at this for a few days now and I just cant get this right.
What I am trying to do:
Within the "divisions" array, I want to remove "Fred" from the "allowedusers" array in each object "division" that he appears in.
What I have tried
I am still very new, about a week in.
I have tried many times, but the closest I have gotten was this:
Org_unit.updateMany({name: "News management"}, { $pull: {'divisions': {'allowedusers': "Fred"}}},{ multi: true })
^^ This deleted the entire division if he appeared in its "allowedusers" array
Any guidance with this is massively appreciated
Thank you in advance.
PS: (Since this is my first question posted, please let me know how I can improve my questions in the future!)
Demo - https://mongoplayground.net/p/kR_NmQNO52y
Use $[]
The all positional operator $[] indicates that the update operator should modify all elements in the specified array field.
db.collection.update({
name: "News management"
},
{
$pull: {
"divisions.$[].allowedusers": "Fred"
}
})

Value update if object exist and create if not under array mongodb

I have a dataset like this:
[
{
"createdate": "2020-06-03T18:30:00.000Z",
"hold": [
{
"time": "12:30",
"user": [
"5ed8ae4891501a1c10246dfe"
]
},
{
"time": "13:00",
"user": [
"5ed8ae4891501a1c10246dfe"
]
},
{
"time": "13:30",
"user": [
"5ed8ae4891501a1c10246dfe"
]
}
],
"_id": "5ed745c38b4d8646601bad1d",
"__v": 0
},
{
"createdate": "2020-06-04T18:30:00.000Z",
"hold": [
{
"time": "12:30",
"user": [
"5ed8ae4891501a1c10246dfe"
]
},
{
"time": "13:00",
"user": [
"5ed8ae4891501a1c10246dfe"
]
},
{
"time": "13:30",
"user": [
"5ed8ae4891501a1c10246dfe"
]
}
],
"_id": "5ed745c3404a701fb888e732",
"__v": 0
}
]
Now I want to update some data on these two enteries, let's say I have to update "13:00" on both the enteries to push 5ed8ae4891501a1c10246dfe, and create/push new object "14:30" with user id i.e 5ed8ae4891501a1c10246dfe.
Also check if id already exist on user array then don't perform anything.
userdata = [{"startdate": "2020, 6, 4", "enddate": "2020, 6, 4", "time": ["12:30", "13:00","13:30"]}]
userdata is the data which we have to update on collection.
What I tried is like:
let userdata = [{ "startdate": "2020, 6, 4", "enddate": "2020, 6, 5", "time": ["12:30", "13:00", "13:30"] }]
const test = async () => {
try {
// I am Using mongoose, so CollectionName is dummy name to share
let data = [];
let getCalenderData = await CollectionName.find(
{ createdate: { $gte: new Date(userdata[0].startdate), $lte: new Date(userdata[0].enddate) } }
).exec();
console.log(getCalenderData)
if (getCalenderData.length > 0) {
data = getCalenderData;
}
console.log(JSON.stringify(data, null, 3))
// So here what I tried to achieve is first on one query pull all data,
// then using filter function to segregate the data,
// then after this set push or pull the data at single query.
} catch (error) {
console.log(error)
}
}
test();
But I have confusion that this approach would be little lengthier than Database query. We have tan option to solve this through javascript but in terms of Database there must me some smart query which perform all these task in a few lines rather than using the Javascript.
Any expert of MongoDB Database, please suggest me how to perform this through DB Query rather than javascript. Any help from the experts will be really really appreciated. Thanks in Advance

Working With Dynamic Multidimensional key-value pairs in JSON

Having a thorny problem and only see similar but also simpler solutions on SO.
Is is possible to generate a dynamic key AND dynamic values using JS/JSON?
For instance, let's say I have JSON like this:
{
"email": "user#someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
I need to go into the fields and for each field (products, wines, fruits) see if a given service is contained within so that I can go back and generate a product or wine or fruit for each service that requires it. But I don't want to repeat the services names more than once. The resulting JSON should look something like this:
{"svc1":["Products"], "svc2":["Products"], "svc3":["Products"], "svc4":["Fruits", "Wines"]}
The hope would be that to generate a dynamic list in Angular I can just turn and loop back through this JSON, pulling out the values for each product, fruit, wine, whatever.
I've been trying a lot of nested for loops and the like but whenever I get more than one layer down the dynamism seems to stop. I'm guessing that for this to work I need to move between JS Objects and JSON?
Right now I'm trying something like this, which isn't quite working, stringify or no. And maybe I'm flip-flopping too much between JSON and JS Objects:
var outObj = [];
var fieldItems;
$.each(jsonObj.custom.fields, function(key, item) {
fieldItems = item;
fieldItems.name = item.name;
$.each(fieldItems.services, function(key, item) {
var serviceName = item;
//check to see if the serviceName already exists
if (outObj.indexOf(serviceName) > -1) {
outObj.serviceName.push(fieldItems.name);
} else {
outObj.push(serviceName);
}
});
});
JSON.stringify(outObj);
console.log("outObj " + outObj);
I get "can't read property 'push' of undefined" errors and the like. Seems this should be possible from a single nested loop, but maybe I need to just do two passes? Any other suggestions?
To me it sounds like overcomplicated solution. You can use basic array methods of javascript to filter out required structure. I am not sure what profiling_value in the presented snippet, so I started from the object structure in OP
var desiredResult = jsonObj.custom.services.reduce(function(result, service){
result[service.name] = jsonObj.custom.fields.filter(function(field){
return field.services.indexOf(service.name) >= 0;
}).map(function(field){ return field.name; });
return result;
}, {});
This gives the expected result for mentioned object.
reduce is required to iterate over all services and accumulate result in one object. Then for each service fields are iterated to filter out only those that contain link to this service. And finally list of filtered fields is transformed (map) into list of strings - their names - and inserted into accumulator

Categories

Resources