I'm trying to delete something from my mongoDb database based on the _id. In my console I keep getting the message that the row was deleting but when I check the database, the object still exists.
this is my function :
function deleteById(){
//5989df87e027c737e5500d17
url_database= mongodb://localhost:27017/incept
MongoClient.connect(url_database, function(err, db) {
if (err) throw err;
var myquery = { _id: '5989df87e027c737e5500d17' };
db.collection("medicament").removeOne(myquery, function(err, obj) {
if (err){
console.log("failed");
throw err;
}
console.log("1 document deleted");
db.close();
});
});
}
This is my json object
{ _id: 5989df87e027c737e5500d17,
medicine_name: 'ada',
dosage_value: 'ads',
dosage_unit: 'MG',
prescribed_for_days: 'ads',
doctor_name: 'asda',
morning_select: '06:00',
afternoon_select: '06:00',
evening_select: '06:00',
night_selct: '06:00' }
Are you sure about the method removeOne. I think to delete you have to use deleteOne.
deleteOne
You need to convert your string _id value into an ObjectID as that's how it's stored in the collection:
const mongodb = require('mongodb');
var myquery = { _id: mongodb.ObjectID('5989df87e027c737e5500d17') };
Related
I have a collection with content:
db.simplecollection2.find()
{ "_id" : ObjectId("5c312200508c979b46d21866"), "artistname" : "The
Tea Party" }
When I change artistname with the following in mongo shell it works
db.simplecollection2.update(
{"_id":ObjectId("5c312200508c979b46d21866")},{"artistname":"new"})
However in javascript I get an Error: SyntaxError: Unexpected token O in JSON at position 7 at JSON.parse (), although I parse a string to object and not object to object.. why is that?
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("simpledb");
var myquery = JSON.parse("{\"_id\":ObjectId(\"5c31184bdb14729aa4806882\")}");
var newvalues = { $set: {"artistname":"cool"} };
dbo.collection("simplecollection2").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("1 document updated");
db.close();
});
Update using ObjectID():
let id = new mongo.ObjectID("5c312200508c979b46d21866");
db.simplecollection2.update({ "_id" : id }, { "artistname" : "new" });
Read More
The line where you call JSON.parse fails because the argument is not a JSON. If you do JSON.stringify({"_id":ObjectId("5c312200508c979b46d21866")}) you'll see that it can't turn that into a string either. The reason being that JSONs can contain strings, booleans, numbers, and arrays. ObjectId("5c312200508c979b46d21866") doesn't resolve to something the browser knows, even though it makes sense in the shell. However, I think if you pass it as a string, it should work as a query for the db.
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("simpledb");
var myqueryObj = {
_id: 'ObjectId("5c312200508c979b46d21866")'
};
var myquery = JSON.parse(JSON.stringify(myqueryObj));
var newvalues = { $set: {"artistname":"cool"} };
dbo.collection("simplecollection2").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("1 document updated");
db.close();
});
I am trying to update an array within a MongoDB collection
It successfully updates when fed the entire array, but the array of numbers breaks and loses all of its values when I use a $Push operation. The array of strings remains intact and successfully updates.
I am trying to update this
var transactionSchema = new Schema({
items: [String],
itemsPrice: [Number],
});
With a single or multiple from value from this.
var itemSchema = new Schema({
itemName: String,
itemPrice: Number,
});
This works when I update using this method
module.exports.updateTransactionById = function (req, res, next) {
Transaction.findOneAndUpdate({_id: req.params.id}, req.body,
{ new: true }, function(err, transaction) {
if (err) return next(err);
if (!transaction) res.status(404).send("No transaction item with that ID!")
return res.status(200).send(transaction);
});
}
// update empty transaction
// RESULT: transaction: {_id=01, items=[a], itemsPrice=[3]}
// update any transaction with some array
// RESULT: transaction: {_id=01, items=[a,b,c], itemsPrice=[1,2,4]}
However, I have to send the entire pre-existing array with each update, which means I would need to query the transactions collection with a GET request before updating it, and that seems unnecessary.
I'm using the $Push method in Mongoose and it doesn't work.
module.exports.updatePushTransactionById = function (req, res, next) {
Transaction.findOneAndUpdate({_id: req.params.id}, { $push: req.body },
{ new: true }, function(err, transaction) {
if (err) return next(err);
if (!transaction) res.status(404).send("No transaction item with that ID!")
return res.status(200).send(transaction);
});
}
// Try updating an empty transaction
//RESULT: transaction: {_id: 01, items=[a], itemsPrice=[]}
// increment subsequent updates
//Result: transaction: {_id: 01, items=[a,b,c,d], itemsPrice=[]}
// Try updating an existing transaction that looks like:
// transaction: {_id: 01, items=[a,b,c,d], itemsPrice=[2,3,4,5]}
// Run push update
//Result: transaction: {_id:01, items=[a,b,c,d,e], itemsPrice=[]
The request body seems to be valid. The casting seems okay, since it accepts the same exact request for the findOneAndUpdate method WITHOUT using a $Push
If this doesn't make sense, here's what I'm trying to accomplish:
A user will click a button to contact the DB and query for the price of an item. The name and price of the item will be fed into a transaction DB. I know holding the details of the transaction in an array is not good, but bear with me.
These are the fetch calls I am using:
GET the price of the item.
function getMenuItemFromDatabase(target) {
var url = '/menus/' + target.id;
return fetch(url, {
method: 'GET'
}).then(function(res){
if(!res.ok) console.log("Error");
else return res.json().then(function(result){
var returnedItem = JSON.parse(result)
return returnedItem[0];
}).catch(function(err){
console.log(err);
throw err;
});
});
}
PUT (by pushing into array) the name and price
function updateTransaction(target){
getMenuItemFromDatabase(target).then(function(menuItem) {
var data = {
items:[menuItem.itemName],
itemsPrice:[menuItem.itemPrice]
}
var url = '/transactions/' + localStorage.transactionID;
fetch(url, {
headers:{
'Content-Type': 'application/json'
},
method: 'PUT',
body: JSON.stringify(data)
}).then(function(res){
if (!res.ok) alert("ERROR!")
else return res.json().then(function(response){
}).catch(function(err) {
console.log(err);
throw(err);
});
});
});
}
I'm pretty confused why this is happening. I've tried looking over the code and playing with the console.log dump in various places, but I'm stuck at this point. I would appreciate any input as to what I must be missing here.
console.log(typeof(req.body.items[0])); // String
console.log(typeof(req.body.itemsPrice[0])); // Number ... so it should work??
I have tried pushing req.body.itemsPrice, req.body.itemsPrice[0], req.body, but the itemsPrice array refuses to update for me.
This is a sample req.body that gets logged by the api
{ items: [ 'Pizza' ], itemsPrice: [ 5.25 ] }
I tried to construct the push query like this:
{ $push: { itemsPrice: req.body.itemsPrice, items: req.body.items} }
I am building backend with MEAN stack, but when I try to update document in the db i am getting an error:
topUp = function(name, amount, callback) {
User.updateOne(
{ "name" : name },
{ $set: { "wallet": amount } },
function(err, results) {
console.log(results);
callback();
});
};
TypeError: User.updateOne is not a function
But e.g. findOne() works fine:
User.findOne({
name: decoded.name
}, function(err, user) {
if (err) throw err;
i
f (!user) {
return res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
} else {
//res.json({success: true, info: {wallet: user.wallet, userPic: user.userPic}});
topUp(decoded.name, amount, function() {
User.close();
});
}
});
"User" is a Mongo model file.
I think it's not defined in the database driver that you might be using. I think you are using Mongoose and updateOne() is not available there. You cannot use all native mongodb functions with all drivers
There is an en existing enhancement request for this https://github.com/Automattic/mongoose/issues/3997 , but maybe the findByIdAndUpdate() method could be a close alternative.
I am doing an online course about MongoDB which is unfortunately a little out of date. It seems some of the functions have changed (course is using version 1.4 while I am using 3.0.)
Here is the code I am having trouble with, which I have tried to bring up to date with the current version of MongoDB:
app.js
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/course', function(err, db) {
if (err) throw err;
db.collection['counters'].findAndModify({
query: {
name: 'comments'
},
update: {
$inc: {
counter: 1
}
},
new: true
}, function(err, doc) {
if (err) throw err;
if (!doc) {
console.dir('No counter found for comments.');
} else {
console.dir('Number of comments: ' + doc.counter);
}
return db.close();
});
});
If I run the same findAndModify through the Mongo shell I get the anticipated result (increment the counter and display the new document,) but when I run this with node it has no effect on the database and throws this error:
TypeError: Cannot call method 'findAndModify' of undefined
Any tips?
Please try:
db.counters('counters').findAndModify
instead of:
db.collection['counters'].findAndModify
use this now:
db.collection('counters').findOneAndUpdate(
{name: 'comments'}, //query
{$inc: {counter: 1}}, //update
{ //options
upsert: true, // create the doc when it's not there
returnOriginal:false // return the modified doc *(new is not supported here!)
},
function(err, r){ //callback
if(err) throw err;
console.log('counter: '+r.value.counter);
}
);
Whoops, I just had the wrong kind of brackets. Should have had:
db.collection('counters')
instead of
db.collection['counters']
Almost like T_G said.
From the mongodb docs:
Existing collections can be opened with collection
db.collection([[name[, options]], callback);
If strict mode is off, then a new collection is created if not already
present.
So you need to do this:
db.collection('counters', function(err, collection){
collection.findAndModify({
query: {
name: 'comments'
},
update: {
$inc: {
counter: 1
}
},
new: true
}, function(err, doc) {
if (err) throw err;
if (!doc) {
console.dir('No counter found for comments.');
} else {
console.dir('Number of comments: ' + doc.counter);
}
});
});
I want to append a value into my Mongoose array but my array never seems to update. I do the following:
In my controller, I append an eventName into the array eventsAttending like so:
$scope.currentUser.eventsAttending.push(event.eventName);
$http.put('/api/users/' + $scope.currentUser._id, $scope.currentUser)
.success(function(data){
console.log("Success. User " + $scope.currentUser.name);
});
I try to update the array like so:
// Updates an existing event in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return handleError(res, err); }
if(!user) { return res.send(404); }
user.markModified('req.body.eventsAttending');
user.save(function (err) {
if (err) { return handleError(res, err);}
return res.json(200, user);
});
});
};
But my array never seems to update. I've also tried the following:
// Updates an existing event in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return handleError(res, err); }
if(!user) { return res.send(404); }
var updated = _.merge(user, req.body);
updated.markModified('eventsAttending');
updated.save(function (err) {
if (err) { return handleError(res, err);}
return res.json(200, user);
});
});
};
With this approach, my array updates properly, but when I try to perform the http put after one time, I get an error saying Error: { [VersionError: No matching document found.] message: 'No matching document found.', name: 'VersionError' }
Here is my UserSchema:
var UserSchema = new Schema({
name: String,
username: String,
eventsAttending: [{ type: String, ref: 'Event'}],
});
If anyone could help that would be much appreciated.
My guess is the object returning from _.merge is no longer a Mongoose model and some information is getting lost in the transform. I would try manually setting all of the fields coming from the request and use events.attending.push() to add to the array, then saving the updated object and see what happens.
Your first example with markModified looks wrong. Looking at the documentation it should be the name of the field that is modified and it appears that you've put the source location for it.
user.markModified('user.eventsAttending')
However that should not be necessary if you use the push method as Mongoose overrides the built-in array function to track changes.