how to update in element array mongodb - mongodb

I have a exemple data:
"_id" : ObjectId("5694ba11b3957b7ff69c4547"),
"name" : "Okas 1",
"job" : {
"name" : "job try1",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5c")
},
"categories" : {
"ss" : [
{
"name" : "10",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5c")
},
{
"name" : "50",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5f")
}
]
}
if I update with new data .
[{
"name" : "800",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5a")
},
{
"name" : "8",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5f")
}]
I should get the data
"_id" : ObjectId("5694ba11b3957b7ff69c4547"),
"name" : "Okas 1",
"job" : {
"name" : "job try1",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5c")
},
"categories" : {
"ss" : [
{
"name" : "10",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5c")
},
{
"name" : "8",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5f")
},
{
"name" : "800",
"_id" : ObjectId("5a6ff9f7a336e3bba40a1d5a")
}
]
}
So I want to update if data exeist just update value but if not exist
add new element in to array categories. I try but not working. the
results are not appropriate

You can do something like this:
model.findOne({_id:req.params.id}, (err, data) => {
if (err) throw err;
if(!data) {
var newData = new model({
name: req.body.name
.....
})
newData.save((err, newdata) => {
// Response
})
} else {
data.name = req.body.name
data.save((err, data) => {
// Response
})
}
I hope this is what you want.

Related

How to remove item in nested collection by id - mongoose

I want to remove a topic by id from the following collection. Here is the hierarchy of the collection - Area.
Area ---
|
---Subjects---
|
Courses---
|
Chapters----
|
Topics
The Area example is as following.
{
"_id" : ObjectId("607f7c67f64e993a5c9b9793"),
"name" : "Automatic Engineering",
"description" : "this is the description.",
"created" : ISODate("2021-04-21T01:14:15.736Z"),
"subjects" : [
{
"description" : "dddd",
"name" : "Transfer Function",
"_id" : ObjectId("607f7c7af64e993a5c9b9794"),
"created" : ISODate("2021-04-21T01:14:34.943Z"),
"courses" : [
{
"description" : "dddd",
"name" : "conception",
"_id" : ObjectId("607f7c9af64e993a5c9b9796"),
"created" : ISODate("2021-04-21T01:15:06.696Z"),
"chapters" : [
{
"description" : "chapter 1",
"name" : "Chapter 1",
"_id" : ObjectId("607f7cb4f64e993a5c9b9798"),
"created" : ISODate("2021-04-21T01:15:32.855Z"),
"topics" : [
{
"description" : "1",
"name" : "Topic 1",
"_id" : ObjectId("607f7ccef64e993a5c9b979b"),
"created" : ISODate("2021-04-21T01:15:58.064Z")
},
{
"description" : "2",
"name" : "Topic 2",
"_id" : ObjectId("607f7cd5f64e993a5c9b979c"),
"created" : ISODate("2021-04-21T01:16:05.663Z")
},
{
"description" : "3",
"name" : "Topic 3",
"_id" : ObjectId("607f7cdcf64e993a5c9b979d"),
"created" : ISODate("2021-04-21T01:16:12.336Z")
}
]
},
{
"description" : "chapter2",
"name" : "Chapter 2",
"_id" : ObjectId("607f7cbcf64e993a5c9b9799"),
"created" : ISODate("2021-04-21T01:15:40.231Z"),
"topics" : []
},
{
"description" : "chapter 3",
"name" : "Chapter 3",
"_id" : ObjectId("607f7cc5f64e993a5c9b979a"),
"created" : ISODate("2021-04-21T01:15:49.000Z"),
"topics" : []
}
]
},
{
"description" : "dddd",
"name" : "exercise",
"_id" : ObjectId("607f7ca6f64e993a5c9b9797"),
"created" : ISODate("2021-04-21T01:15:18.465Z"),
"chapters" : []
}
]
},
{
"description" : "this is the example",
"name" : "State Space Equation",
"_id" : ObjectId("607f7c8ef64e993a5c9b9795"),
"created" : ISODate("2021-04-21T01:14:54.056Z"),
"courses" : []
}
],
"__v" : 0
}
And I need to remove topic object in chapters array. So this is what I have done.
areaModel.findOneAndUpdate({
'_id': req.body.area_id,
'subjects._id': req.body.subject_id,
'courses._id': req.body.course_id,
'chapter._id': req.body.chapter_id
}, {
"$pull": {
"subjects.$.courses.$.chapters.$.topics": {
_id: req.body.topic_id
}
}
}, (err, result) =>{
if (err) {
return res.json({success: false, msg: err});
} else {
return res.json({success: true, msg:"successfully removed" });
}
});
By using $pull method of mongoose, I could remove the course from the area easily. But it was impossible for me to remove the more nested items like chapters and topics.
How can I solve this issue?
you can do so with the use of arrayFilters like so:
db.collection.updateOne(
{
_id: ObjectId("607f7c67f64e993a5c9b9793")
},
{
$pull: {
"subjects.$[s].courses.$[c].chapters.$[ch].topics": {
_id: ObjectId("607f7ccef64e993a5c9b979b")
}
}
},
{
arrayFilters: [
{
"s._id": { $eq: ObjectId("607f7c7af64e993a5c9b9794") }
},
{
"c._id": { $eq: ObjectId("607f7c9af64e993a5c9b9796") }
},
{
"ch._id": { $eq: ObjectId("607f7cb4f64e993a5c9b9798") }
}
]
})
https://mongoplayground.net/p/kVyV27nnkII
Try it:
areaModel.findOneAndUpdate(
{ _id: req.body.area_id },
{
$pull: {
"subjects.$[].courses.$[].chapters.$[].topics": {
_id: req.body.topic_id,
},
},
}
);

How to upsert nested array object mongodb

I have a document which looks like this
{
_id:'asasasasa23sdsdsd',
source:'page',
url:[]
}
I need to upsert some values/objects to the url array. the objects that need to be upserted looks like this.
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
Then it would look like this
{
_id:'asasasasa23sdsdsd',
source:'page',
url:[{
"type" : "admin",
"value" : "hello admin",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
},
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
]
}
Here the id and the type fields are unique. I need to insert them if they do not exist or update them if they do.
This is the code that I have tried
db.collection(TABLE_NAME).update(
{ source: data.source },
{
source: data.source,
url: [data.urls]
},
{ upsert: true }
);
With this, it just replaces the array object with a new object. How to upsert instead of replacing the object?
I think this code will help.
let arr = [
{
"type" : "admin",
"value" : "hello admin",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
},
{
"type" : "blog",
"value" : "hello blog",
"id" : "1815f620-b45c-4230-85bb-7ba90ac330ed",
"datetime" : "2019-12-26 15:58:33"
}
];
db.users.update(
{ _id: doc._id },
{
$set: {
"url": arr
}
}
);

Update Documents From Each Value of an Input Array

I have a JSON with two keys: id and name. I need a way to insert that id on my collection (querys.project.name) when the name on it and on the JSON matches.
Example of my JSON:
var projectsMysql = [
{
"id" : 1,
"name" : "Something"
},
{
"id" : 5,
"name" : "Something else"
},
{
"id" : 50,
"name" : "Some name"
}]
and in my collection about 60 documents like this one:
{
"_id" : ObjectId("58e42bf30a34d641be6c25c2"),
"folio" : "R-666-69",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Something else"
// "projectsMysql_id" : 5 THIS SHOULD BE PLACED HERE
},
}
I wrote a function for Node.js but now I need to run this directly on the mongo shell, I read that I need to use cursor.forEach() method but I couldn't find a way to do it, this is my function:
projectsMysql
.forEach(function(project){
var query = {
name: project.name
}
db.getCollection('requests')
.find(query)
.exec(function(err, response){
if (err) {
return
}
if (response) {
db.getCollection('requests')
.update({id: response.id}, {$set: {
'project.projectsMysql_id': project.id
console.log("element inserted");
}})
.exec(function(err){
});
}
});
});
Can you point me in to the right direction?
What you want here is bulkWrite(), where instead of actually executing an update() for each document within the projectsMysql array you actually just construct a "single" statement made of "multiple" updates which sends to the server and updates the appropriate documents:
db.getCollection('requests').bulkWrite(
projectsMysql.map(({ id, name }) =>
({ "updateOne": {
"filter": { "project.name": name },
"update": { "$set": { "project.id": id } }
}})
)
)
If you expect "multiple documents" to match the condition, then simply switch to updateMany:
db.getCollection('requests').bulkWrite(
projectsMysql.map(({ id, name }) =>
({ "updateMany": {
"filter": { "project.name": name },
"update": { "$set": { "project.id": id } }
}})
)
)
Your array is already in memory so there is not really any point to doing any other kind of "iteration" and you can simply .map() the properties onto the updateOne statements ( or updateMany ) and issue them all in one statement. Updates are only actually processed where there is a "match" and indeed where there is something to actually update, as existing values will be left alone using $set.
To Demonstrate, considering these documents:
{
"folio" : "R-666-69",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Something else"
}
},
{
"folio" : "R-666-67",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Some name"
}
},
{
"folio" : "R-666-68",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Some name"
}
}
{
"folio" : "R-666-64",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Something"
}
},
{
"folio" : "R-666-65",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Different"
}
}
The the following update:
var projectsMysql = [
{
"id" : 1,
"name" : "Something"
},
{
"id" : 5,
"name" : "Something else"
},
{
"id" : 50,
"name" : "Some name"
}]
db.getCollection('requests').bulkWrite(
projectsMysql.map(({ id, name }) =>
({ "updateMany": {
"filter": { "project.name": name },
"update": { "$set": { "project.id": id } }
}})
)
)
Returns the response:
{
"acknowledged" : true,
"deletedCount" : 0,
"insertedCount" : 0,
"matchedCount" : 4,
"upsertedCount" : 0,
"insertedIds" : {
},
"upsertedIds" : {
}
}
And alters the matched documents accordingly:
{
"_id" : ObjectId("5b206a48f7fa0c655d90157a"),
"folio" : "R-666-69",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Something else",
"id" : 5
}
}
{
"_id" : ObjectId("5b206a48f7fa0c655d90157b"),
"folio" : "R-666-67",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Some name",
"id" : 50
}
}
{
"_id" : ObjectId("5b206a48f7fa0c655d90157c"),
"folio" : "R-666-68",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Some name",
"id" : 50
}
}
{
"_id" : ObjectId("5b206a48f7fa0c655d90157d"),
"folio" : "R-666-64",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Something",
"id" : 1
}
}
{
"_id" : ObjectId("5b206a48f7fa0c655d90157e"),
"folio" : "R-666-65",
"alias_purchase" : "Deal",
"project" : {
"description" : "",
"name" : "Different"
}
}

I Want add if data in element array not exists

I have this data in database.
{
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b"),
"name" : "Jhones Crows",
"hobbies" : [
{
"name" : "swim",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b")
},
{
"name" : "run",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7c")
}
]
}
And I try to add data into hobbies if data in hobbies not exist. I try this :
db.getCollection('milo').update(
{'_id' : ObjectId("5a6ef287370ff5dc3d6fda7b"), 'hobbies.name' : 'sport'},
{ $addToSet : { 'hobbies' : {
'name' : 'sport',
}}
},
{upsert : true}
)
And I want data result like this :
{
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b"),
"name" : "Jhones Crows",
"hobbies" : [
{
"name" : "swim",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b")
},
{
"name" : "run",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7c")
},
{
"name" : "sport",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7a")
}
]
}
so suppose the value of sport is not in hoobies.name. will add a new name object in the hobbies. but if there is not change anything

need to filter query to get selected object in mongodb

I have the below document.
I want to return "employeedata" containing only those array objects (family, academic etc.) for which status is "current"
{
"_id" : ObjectId("5a1fe7ed1e9fdd17285ac13f"),
"createdby" : "admin",
"details" : [
{
"_id" : ObjectId("5a1fe81f1e9fdd17285ac14a"),
"employeedata" : {
"createddate" : "2017-11-30T11:13:57.290Z",
"family" : [
{
"status" : "current",
"_id" : ObjectId("5a1fe81f1e9fdd17285ac153")
}
],
"academic" : [
{
"status" : "archive",
"_id" : ObjectId("5a1fe81f1e9fdd17285ac159")
},
{
"status" : "current",
"_id" : ObjectId("5a1fe8a71e9fdd17285ac15d")
}
],
"company" : [
{
"status" : "archive",
"_id" : ObjectId("5a1fe81f1e9fdd17285ac150")
},
{
"status" : "current",
"_id" : ObjectId("5a1fe88e1e9fdd17285ac15c")
}
],
"other" : [
{
"status" : "current",
"_id" : ObjectId("5a1fe81f1e9fdd17285ac154")
}
]
}
}
]
"confirmed" : true,
}
You can try following to filter the object as it is an complex object we will have to loop through the complete object and modify it at run time.
var data = JSON.parse('{"_id":"5a1fe7ed1e9fdd17285ac13f","createdby":"admin","details":[{"_id":"5a1fe81f1e9fdd17285ac14a","employeedata":{"createddate":"2017-11-30T11:13:57.290Z","family":[{"status":"current","_id":"5a1fe81f1e9fdd17285ac153"}],"academic":[{"status":"archive","_id":"5a1fe81f1e9fdd17285ac159"},{"status":"current","_id":"5a1fe8a71e9fdd17285ac15d"}],"company":[{"status":"archive","_id":"5a1fe81f1e9fdd17285ac150"},{"status":"current","_id":"5a1fe88e1e9fdd17285ac15c"}],"other":[{"status":"current","_id":"5a1fe81f1e9fdd17285ac154"}]}}]}');
function createObject() {
for (var obj in data.details[0].employeedata) {
if (Array.isArray(data.details[0].employeedata[obj])) {
data.details[0].employeedata[obj].filter(function (value, index) {
if (value.status !== 'current') {
//return value;
data.details[0].employeedata[obj].splice(index, 1);
}
})
}
}
}