mongoose mode.findOneAndUpdate query not working - javascript

I have this:
var id = req.body.id;
var query = {'_id': req.body.id, 'site': req.body.location, 'content': req.body.services, 'updatedByCNUM': req.body.cnum};
ServicesModel.findOneAndUpdate(query, id, {upsert: true}, function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});
console.log(req.body.Services, req.body.location)
I am new to mongoose, and I am trying to do an update query. I basically have the ID of the document, so I want to find it, and then update it with the new values (all being based into query). How can I do this? This above is not working, it says :
TypeError: Cannot convert undefined or null to object
thanks 4 the help

ServicesModel.findOneAndUpdate(
{_id : req.body.id},
{ $set: { site: req.body.location, content: req.body.services, updatedByCNUM: req.body.cnum } },
, {upsert: true, new: true}, function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});

var id = req.body.id;
var query = {'_id': req.body.id, 'site': req.body.location, 'content': req.body.services, 'updatedByCNUM': req.body.cnum};
ServicesModel.findOneAndUpdate(
{_id : req.body.id},
{ $set: { query} },
function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});
Note: $set replaced every data there before. to add a new data on the previous one you need to use $pull or $push. you can check the docs here

Related

await with .then behavior [duplicate]

I have an issue I've not seen before with the Mongoose findByIdAndUpdate not returning the correct model in the callback.
Here's the code:
var id = args._id;
var updateObj = {updatedDate: Date.now()};
_.extend(updateObj, args);
Model.findByIdAndUpdate(id, updateObj, function(err, model) {
if (err) {
logger.error(modelString +':edit' + modelString +' - ' + err.message);
self.emit('item:failure', 'Failed to edit ' + modelString);
return;
}
self.emit('item:success', model);
});
The original document in the db looks like this:
{
_id: 1234
descriptors: Array[2],
name: 'Test Name 1'
}
The updateObj going in looks like this:
{
_id: 1234
descriptors: Array[2],
name: 'Test Name 2'
}
The model returned from the callback is identical to the original model, not the updatedObj.
If I query the db, it has been updated correctly. It's just not being returned from the database.
This feels like a 'stupid-user' error, but I can't see it. Any ideas greatly appreciated.
In Mongoose 4.0, the default value for the new option of findByIdAndUpdate (and findOneAndUpdate) has changed to false, which means returning the old doc (see #2262 of the release notes). So you need to explicitly set the option to true to get the new version of the doc, after the update is applied:
Model.findByIdAndUpdate(id, updateObj, {new: true}, function(err, model) {...
app.put("/vendor/:id",async (req,res)=>{
res.send(req.params)
await ModelName.findByIdAndUpdate(id, {type: change}, function(err, docs){
if(err){
conslole.log(err)
}else{
console.log(docs)
}
})
})
Example:
app.put("/vendor/:id",async (req,res)=>{
res.send(req.params)
const data = await userModel.findByIdAndUpdate(req.params.id, {isVendor: true},
function(err, docs){
if(err){
conslole.log(err)
}else{
console.log(docs)
}
})
})

How do I merge into an existing unique id in MongoDB with NodeJS?

I want to sum a documents field when I insert a new entry that has a duplicate unique id. This is what I have so far:
MongoClient.connect(process.env.MONGODB_URI || process.env.DB_CONNECTION, { useUnifiedTopology: true, useNewUrlParser: true }, function (err, db) {
if (err) throw err;
const dbo = db.db("mydb");
const messageTable = dbo.collection("comments");
for(var key in words){
let myobj =
[{
_id: key,
frequency: words[key]
}];
messageTable.insertMany(myobj, function(err, res){
if (err) throw err;
console.log("documents inserted");
});
messageTable.aggregate([
{ $match: { _id: key } },
{
$group: {
_id: key,
total: {
$sum: "$frequency"
}
}
},
{ $merge: { into: "comments", whenMatched: "replace" } }
]);
}
})
From reading the docs I tried to use the aggregate method to merge new entries if the key already exists as a unique id. This is not currently working. How would I merge duplicate documents in my MongoDB using NodeJS?
I have figured out a way to do this by reading the docs and with the help of a reddit user. If anyone wants to do something similar this is the easiest method:
messageTable.findOneAndUpdate({ "_id" : key },{$set: { "_id" : key}, $inc : { "frequency" : words[key] }},{upsert: true}).then(
console.log("document updated or inserted")
)
With this method the first argument is your query, the second changes the first match which in my case increments the frequency field, and the third are options for the method. The upsert option has a default value of false but when true creates a new document if one does not already exist. If you wish to read more you can find info here

MEAN App - Updating table after DB Collection update

I 'm trying to keep my table data in sync with the db data.
On Data Change:
$scope.changeStatus = function($event,label,status){
var target = $event.currentTarget;
target = $(target).parents('tr').attr('id');
$http({
method: 'POST',
url: '/update',
params: {
trgt : target,
label : label,
labelstatus : status,
searchQuery : $scope.search
}
})
.success(function(data){
console.log(data);
$scope.events = data;
})
.error(
function(error){
console.log(error)
});
}
Then:
app.post('/update', function(req,res){
ImportCollection.findOne({ _id : req.query.trgt },function(err,doc){
doc.label.label = req.query.labelname;
doc.label.status = req.query.labelstatus;
doc.save();
});
// UNTIL HERE EVERYTHING WORKS JUST FINE
if(req.query.searchQuery){
ImportCollection.find({$or:[
{'localizedData.0.title' : {'$regex': req.query.searchQuery, $options: 'i' }},
{'licensor.name' : {'$regex': req.query.searchQuery, $options: 'i'}}
]})
.exec(function(err, imports){
if(err) throw err
res.json(imports)
})
} else{
ImportCollection.find({},function(err, imports){
if(err) throw err
res.json(imports)
})
}
});
But then the response that should update the table data, is allways one request behind.
So current Data = Live, I set it to QA and nothing happens. The table is still displaying Live. Once I change it now, lets say to DENIED, the table displays QA. I hope it's clearer now.
Does anyone have an idea?
Passing the find() block as a callback function to the doc.save() method worked for me:
doc.save(function(err){
if (err) throw error
var query = req.query.searchQuery;
if(query) {
ImportCollection.find({$or:[
{'localizedData.0.title' : {'$regex': req.query.searchQuery, $options: 'i' }},
{'licensor.name' : {'$regex': req.query.searchQuery, $options: 'i'}}
]}).exec(function(err, imports){
if(err) throw err
res.json(imports)
});
} else{
ImportCollection.find({}).exec(function(err, imports){
if(err) throw err
res.json(imports)
});
}
});

Mongo $addToSet with multiple values correct syntax

I have this mongoose schema:
var listingSchema = new Schema({
street : String,
buildingNumber : Number,
apartmentNumber : Number,
UsersAndQuestions: [{
userID: String,
questionID: [String]
}]
});
And I just want to update it with a new entry to UsersAndQuestions which will consist of a userID which is a String, and a questionID which is also a String (but needs to be inserted into an array).
I am using this PUT request:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addUserInput/:userid/:listingid/:questionid')
So I have all the necessary parameters in hand.
Usually, when I wanted to update a field in a schema I used this code that I wrote:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addReportedUser/:userid/:listingid', function (req, res) {
var listingToUpdate = req.params.listingid;
var idToAdd = req.params.userid;
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {reportedUsersIDs: ObjectId(idToAdd)}}
, function (err) {
if (err) {
res.send("There was a problem adding the reportedUserID to the listing" + err);
}
else {
console.log("Success adding reportedUserID to listing!");
}
})
});
You can see I used $addToSet and it worked well. But now I want to add two parameters to a field which is an array. I thought about doing something like this:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addUserInput/:userid/:listingid/:questionid', function(req,res){
var listingToUpdate = req.params.listingid;
var idToAdd = req.params.userid;
var questionToAdd = req.params.questionid;
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {UsersAndQuestions.userID : ObjectId(idToAdd), UsersAndQuestions.questionID : ObjectId(questionToAdd)}}
, function (err) {
if (err) {
res.send("There was a problem adding the user and question to the listing" + err);
}
else{
console.log("Success adding user and question to the listing!");
}
})
});
But I'm obviously getting a SyntaxError.
What is the correct syntax for doing what I tried to do?
Thanks a lot! :)
You need to add object to set UsersAndQuestions:
{$addToSet: {UsersAndQuestions: { userID: idToAdd, questionID: questionToAdd } }}
UPDATE.
I would do it with two queries:
Listing.update({_id: ObjectId(listingToUpdate), 'UsersAndQuestions.userID': idToAdd},
{"$addToSet": {"UsersAndQuestions.$.questionID": questionToAdd}}
, function (err, result) {
if(result.n === 0){
//we haven't found document with the userId - idToAdd
//we need to insert to UsersAndQuestions document with this user
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {UsersAndQuestions: { userID: idToAdd, questionID: questionToAdd } }},
function(err, res){
})
}
})

MongoJS Node findOne falsely returns no results

Using MongoJS: https://github.com/mafintosh/mongojs
Finds everything
db.users.find({}, function(err,users){
if (err) throw err;
console.log(users);
})
Returns the user. looks great
[{ _id: 53f2faa6aed1689e84982b8b,
facebook: {
email: 'myname#gmail.com',
name: 'Juan Atkins',
id: '764969936' },
__v: 0
}]
When I try to find that user by his id: failed
db.users.findOne({
_id: '53f2faa6aed1689e84982b8b'
}, function(err, user) {
if (err) throw err;
console.log(user);
});
returns []
I know there is data in the DB. I've tried searching by a different key (like name). Why can't it find the data?
you have to use ObjectId: http://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html
db.users.findOne({
_id: new ObjectID('53f2faa6aed1689e84982b8b')
}, function(err, user) {
if (err) throw err;
console.log(user);
});

Categories