can't update DB using put request in express.js - mongodb

I'm trying to update the languages_known through post request to the mongodb collection using the body of the request but its not updating i'm newbie any help would be really appreciated.
mongodb document :
{
"_id": {
"$oid": "5d63e81c342987154cdc698e"
},
"name": "anjana",
"email": "anju#gmail.com",
"age": "22",
"languages_known": [
"Bengali",
"Kannada"
],
"phone": "684684684846"
}
server code :
app.put('/students/add',function(req,res){
var myobj={
$set:{_id:require('mongodb').ObjectID(req.body.id),languages_known:req.body.remove}
}
db.collection('students').updateOne({languages_known:req.body.add},myobj,function(err,result){
if(err){throw err}
console.log("updated")
})
})
request body :
{
"id":"5d63e81c342987154cdc698e",
"remove": ["Bengali", "Kannada"],
"add": ["Tamil", "Punjabi"]
}
I've expected to update the languages_known field using this req through postman to this id

Ok this issue is with the query, you can't update _id of a document like that, also as your requirement is not to do that, Please try this :
server code :
// replace languages_known with new languages based on _id, in case if you wanted to update the array you can use $push
app.put('/students/add', function (req, res) {
const id = require('mongodb').ObjectID(req.body.id)
let updateQuery = {
$set: { languages_known: req.body.add }
}
db.collection('students').updateOne({ _id: id }, updateQuery, function (err, result) {
if (err) { throw err }
console.log("updated")
})
})

Related

Isn't it possible to concat new value to a field in MongoDB document while updating it?

I have few documents in a MongoDB Collection and each has a unique field called "requestid". Now I need to update a field "requeststatus" by concatenating a new value to an existing one in NodeJS application. I started using MongoDB for very recent and have less exposure in it's features.
After doing some research I got to know I could use "$set" with "$concat"
Updating with filter & options:
var filter = { requestid: data.requestid };
var updateDoc = { $set: { requeststatus: { $concat: ["$requeststatus","-",`. ${data.status}`] } } };
var options = { multi: true };
var jobDetails = { filter, updateDoc, options };
NodeJS code:
async function updateJobDetails(connection, data, mongoDetails){
const result = await connection.db(mongoDetails.mongoDatabase).collection(mongoDetails.collection).updateOne(data.filter, data.updateDoc, data.options);
}
This is not doing as expected, instead it's adding the new concatenated value as array of Object into MongoDB collection.
Existing document:
{
"_id": {
"$oid": "6307120d3oiu895oi9e82eea5"
},
"requestid": "123456789",
"iscancelled": true,
"organizationid": "3",
"instanceid": "172",
"offerid": "offer123",
"promotionid": "promo123",
"jobtype": "portaljob123",
"jobid": "job123",
"requeststatus": "began"
}
Updated document:
{
"_id": {
"$oid": "6307120d3oiu895oi9e82eea5"
},
"requestid": "123456789",
"iscancelled": true,
"organizationid": "3",
"instanceid": "172",
"offerid": "offer123",
"promotionid": "promo123",
"jobtype": "portaljob123",
"jobid": "job123",
"requeststatus": {
"$concat": ["$requeststatus", "-", "tigger_datalink stopped since request was cancelled"]
}
}
Is there anything that I am doing wrong here? I even tried updateMany() but of no use. Run it as many times as desired it won't concat but keep updating same value as Object Any help is appreciated here.
(Working) Updated NodeJS code:
async function updateJobDetails(connection, data, mongoDetails){
const result = await connection.db(mongoDetails.mongoDatabase).collection(mongoDetails.collection).updateOne(data.filter, [data.updateDoc], data.options);
}
In order to use an existing field's data you need to use an update with a pipeline.
Try using your updateDoc inside a pipeline, like this:
var filter = { requestid: data.requestid };
var updateDoc = { $set: { requeststatus: { $concat: ["$requeststatus","-",`. ${data.status}`] } } };
var options = { multi: true };
var jobDetails = { filter, [updateDoc], options };
See how it works on the playground example

Auto insert non existing value with findOneAndUpdate and upsert

My use case :
=> UPDATE : set the current date if I found a specific email (working)
=> INSERT : a specific email with date to null if the email passed in the request is not found (not working)
I thought upsert were supposed to insert if the specific email was not found, but for some reason, it's not.
JSON Structure
"listener": [
{
"email": "email",
"date": "2019-06-23T00:22:52.190Z"
}
],
Route
exports.add_listener = function (req, res) {
Playlist.findOneAndUpdate(
{"platform.strauss": req.body.url},
{$set: {"listener.$[elem].date": new Date()}},
{
arrayFilters: [{"elem.email": req.body.email}],
upsert:true,
new:true,
}, function (err, data) {
err ? console.error(err) : res.status(200).send(data);
}
)
};

Why am I unable to specify a field to return with the projection parameter in MongoDB? [duplicate]

dbo.collection("users")
.findOne({email: emailGiven, "friends.email": element.email},
{ friends: { $elemMatch: { email: element.email } } },
function(errT, resultT) {})
I have the query above in node.js but for some reason the query's elemMatch part doesn't work on node.js but when I execute the same query in mongo terminal it works, so I'm thinking maybe node.js doesn't support $elemMatch? If this is the case, could anyone tell me what would be the equivalent of this query in node.js?
Sample data from my DB:
/* 4 */
{
"_id" : ObjectId("5ad20cef8248544860ce3dc1"),
"username" : "test",
"email": "",
"fullName" : "",
"friends" : [{email: "",
status :""}],
"alarms": [ {"id":111,
"title": "TITLE",
"location": "",
"startTime": "10-10-1996 10:18:00",
"endTime": "10-10-1996 10:18:00" }, {},{}
],
"pnumber" : ""
}
The node.js driver findOne has a different call signature than the findOne in the MongoDB shell. You pass the field selection object as the projection element of the options parameter:
dbo.collection("users")
.findOne({"friends.email": email},
{projection: { friends: { $elemMatch: { email: email } } } },
function(errT, resultT) {...});
If you want to find for any values which is stored in some variable, you use regex for that. Your query should look like
dbo.collection("users").findOne({
email: new RegExp(emailGiven, 'i'),
"friends.email": new RegExp(element.email, 'i')
}, {
friends: {
$elemMatch: {
email: new RegExp(element.email, 'i')
}
}
}, function(errT, resultT) {})
i is for case insensitive comparison here

mongooseJS returning an object after update?

Is it possible to return a document after updating it?
my current code looks something like this:
module.exports.updateEmail = function(id, data, callback) {
User.findByIdAndUpdate( id, {
$set: { "email": email }
}, callback);
}
how would I pull the User document and pass it back?
add {new : true} update option, to return the updated document, the callback will have the updated document you can return it
module.exports.updateEmail = function(id, data, callback) {
User.findByIdAndUpdate( id,
{$set: { "email": email }},
{new : true}, // to return updated document
callback
);
}

Update Record in MonogoDB using Node-Red

I'm new in Node-Red and MongoDB.
I need to update a document in collection using Node-Red.
Here is my code in Function node:
var newMsg = msg;
newMsg.operation = 'findAndModify';
newMsg.payload = {
query: { "UserKey": "mykey" },
update: { $set: {"Locked": false } }
};
return newMsg;
But got the below error
"Monog Error: need remove or update".
Edit:
Although the below code is working fine in Mongo shell.
db.Users.findAndModify({
query: { "UserKey": "mykey" },
update: { $set: { "Locked": false } }
})
Thanks
findAndModify is not one of the supported methods for the mongo node, you will have to do it as a 2 stage process.
Use Mongo In node to do a find, then update the payload and feed it into a Mongo Out node to do a store
#phani-indra, for example, if you have a collection of users with document:
{ "chatid" : 324323,
"alert" : false,
"accesslevel" : 4,
"_id" : ObjectId("5d76b33c6ff21e0155d035a0")
}
and you want to change key "alert" to true, so your function node in NodeRED will looks something like:
var newMsg = {
'collection': 'users',
'operation': 'update',
'query': {
chatid : 324323
},
'payload': {
$set: {
alert : false
}
}
};
return newMsg;
Then feed function node into a Mongo Out node.