PATCH method to MongoDB using Node - node.js

I want to create a PATCH method for my API but there is something I don't understand. Imagine I have the following document in my MongoDB database:
{
_id : ObjectId(1234...),
name : "bob",
age : 30
}
Now I would like to update this document but I don't know what keys my API will receive. So imagine I make a request in order to change the age but also add a last_name.
The request result would be like this:
{
_id : ObjectId(1234...),
name : "bob",
last_name : "smith",
age : 44
}
The main problem here is that I don't know the arguments I will receive.
My goal is to update the values of the existing keys and add the keys that are not in the document.
Any idea?
Thanks

You want to use the $set operator.
What this does is only updates the keys that are sent in the update query. Without $set, it will overwrite the whole object, which is obviously not what you want.
app.patch('/user/:id', function (req, res) {
var updateObject = req.body; // {last_name : "smith", age: 44}
var id = req.params.id;
db.users.update({_id : ObjectId(id)}, {$set: updateObject});
});
I'm assuming a couple things here:
You are using express.
You are using either the mongodb driver or mongojs npm module

Related

Add and Remove Within Mongoose

{
"_id" : 1,
"_name" : "peter",
"favourites" : [
{
"user_id" : 1
},
{
"user_id" : 2
}
]
}
I have this schema within Mongo, and I'm using Node/Express/Mongoose to manage my stack. I'm new to this particular stack and I have a 'favourite' button on the website I'm building. What's the best way to add/remove from favourites?
Do I really need to setup two routes, one for POST and another for PUT? I'm not sure what the best way is to solve this particular problem, I've done some searching and I've not found anything that relevant.
I'm not going to give you the full answer as it's always good to learn, so I've give you 90% of what I think is what you're looking for. Do a check for the name and if it doesn't exist within the favourites array, do the following:
db.collection.update(
{ "username": "walterwhite" },
{ $push:
{
favourites: [ { "user_id": "7" } ]
}
}
)
First of all you will need routes for any of the actions. It's probably the best practice to use the HTTP Verbs (GET/POST/PUT/DELETE etc.). Then your routes would look something like this: (this could be wrapped in a file that contains all routes and later required in the main app file (ex. app.js).)
module.exports = function (router) {
router.route('/favourites')
.get(function (req, res, next) {
// Code for getting all items
})
.post(function (req, res, next) {
// Code for inserting new item
})
.delete(function (req, res, next) {
// Code for deleting an item
});
}
Then you will need to build a form with fields corresponding to the item's properties and use POST as a submit method. You will need it for inserting (adding) new items. The request sent from the form, will send you to the post route, where you will handle your logic for appending item to the list.
To implement the deletion you will have to send a DELETE, request passing an identifier of the item you'd want to delete. You will handle this code in the delete route.
Of course, the get route is for getting all items in the collection for further processing or visualizing.
you must create an object id associated to every user_id. you can create such id's using.you can associate multiple models with mongoose population
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
"favourites" : [
{
"_id" : ObjectId("57338c9cc5c8cf74181b4cff"),
"user_id" : 1
},
{
"_id" : ObjectId("5734588e5a54d45434693a09")
"user_id" : 2
}
]
either render the page or send a json object as response with the object id in it as per your setup.
user_id-2
user_id-1
now you can make an ajax request with the object id when clicked on a particular <a> tag.you can achieve this with jquery. Then remove the user associated with that id from your favorites.
If you add more details.I can give you a specific answer.

Mongoose unique validation error even though unique constraint is not there

var schema = new Schema({
_id: Schema.ObjectId,
email: {type: String, required: true}
});
Previously email field was unique (with unique constraint)
Now I removed unique constraint, then also it's giving unique validation error. I have restarted mongo then also it's throwing error.
Any Idea?
When you remove the unique constraint in the schema definition, you were supposed to manually remove it from the database as well. You can do this either in mongo shell by using the dropIndex() method or in your application using the native node.js driver's dropIndex() method of the collection.
You may need to confirm this first by checking the indexes currently in the database; you will most probably find the email unique index created when you populated the collection after defining the schema in Mongoose.
You can issue the command in mongo shell, supposing you have a collection named users in your database named test:
> db.users.getIndexes()
which will show the current indexes, you may see in your console an array like the following:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.users"
},
{
"v" : 1,
"unique" : true,
"key" : {
"email" : 1
},
"name" : "email_1",
"ns" : "test.users",
"background" : true,
"safe" : null
}
]
For a solution in your application code, supposing you have a Mongoose model called User that has the defined schema above, you can call the getIndexes() native node.js driver's collection method:
User.collection.getIndexes(function (err, results) {
// Handle errors
});
In mongo shell, you can then go ahead and remove the email index with the dropIndex() method :
> db.users.dropIndex("email_1")
In your application code, you can also issue the command via the Mongoose model for the collection, and call the native node.js driver's dropIndex() method of the collection:
User.collection.dropIndex("email_1", function (err, results) {
// Handle errors
});
You can also follow the below steps.
Delete users collection from database.
Save user model(Schema) file and test.

Updating more than one MongoDB document in NodeJS doesn't seem to work

So I know this question has been asked many times but I've looked it up for over 30 minutes and I honestly can't find what I'm doing wrong.
I want to update my mongo data
Here's an example of two documents
{
"_id" : ObjectId("561e34c68b7639481c38ce62"),
"id" : "1657999143",
"timeTakenAt" : 1444820166833.0000000000000000,
"userName" : "a",
"__v" : 0
}
{
"_id" : ObjectId("561e34c68b7639481c38ce63"),
"id" : "1659143",
"timeTakenAt" : 1444820166833.0000000000000000,
"userName" : "b",
"__v" : 0
}
I want to change to usernames to something else.
For example to JOHN CENA.
Here is the code I'm using.
...
var UserModel = mongoose.model('userSchema', userSchema);
...
updateUsers()
function updateUsers(){
UserModel.update({}, {$set: {userName: 'JOHN CENA'}}, {multi:true})
}
But it doesn't work, not even a single document is changed.
I've also found that some people used
UserModel.update({}, {$set: {userName: 'JOHN CENA'}}, false,true)
But that one gives me an error, so I guess it's code from an older version.
However, if I use
UserModel.update({}, {$set: {userName: 'JOHN CENA'}}, {multi:true}, updateUsers)
(Which obviously loops forever since it calls itself). Every single document ends up being updated with the JOHN CENA user name.
I don't understand what's going on here, can anybody help me please ?
EDIT : In the comments below a user suggested adding an empty callback. Which I did and now it works as intended. My thanks go to him (#Sergio Tulentsev) and I hope this thread will help somebody else in the future.
As noted in the docs for update, if you don't want to provide a callback, you need to call exec on the returned Query to execute it:
To update documents without waiting for a response from MongoDB, do
not pass a callback, then call exec on the returned Query
So either chain an exec call on your update or provide a callback:
function updateUsers(){
UserModel.update({}, {$set: {userName: 'JOHN CENA'}}, {multi:true}).exec();
}
OR
function updateUsers(){
UserModel.update({}, {$set: {userName: 'JOHN CENA'}}, {multi:true},
function(err, numAffected) {...});
}

MongoDB _id is convert to ObjectID automatically, but sometime it is not.

I am using a wrapper called mongoskin to access mongoDB. mongoskin is a simple wrapper around mongoDB javascript api.
But when I write to mongoDB, sometimes _id is converted to ObjectID, sometime is it not. The different behavior causes many problem when I have to compare _id. For example:
The following documents in company collection, "creator" is not converted to ObjectID, but item in "clients" is converted to ObjectID automatically.
> db.company.find()
{ "_id" : ObjectId("53d4b452f5b25900005cb998"), "name" : "Default Company Co.", "clients" : [ ObjectId("53d4b452f5b25900005cb999"), ObjectId("53d4b452f5b25900005cb99a") ] }
{ "_id" : ObjectId("53d4b452f5b25900005cb999"), "name" : "client company for 777 - updated", "creator" : "53d4b452f5b25900005cb998", "ssn" : "12-123-1234" }
This is the nodejs code I used to assign _id for "creator"
clientCompany.creator = req.session.user.company_id;
This is the nodejs code I used to assign _id for "clients"
var updateObj = {$addToSet: {clients:resultClient._id} };
// update creator company.clients
creatorCompany.update(updateObj, function(err, result) { ...}
When I console.log "req.session.user.company_id" and "resultClient._id", they both looks like a string type. How come one end up as ObjectID in MongoDB? If there is an auto conversion, how do I make this behavior consistent?
Thanks!
I'm guessing resultClient is the result of a query and req.session.user.company_id a string from your web application? In that case you need to create an ObjectId from the string:
clientCompany.creator = mongoskin.ObjectID(req.session.user.company_id);

mongoose findOne returning null after changing string key field

I'm using mongo db 2.6 and I have a users collection.
The users Schema has an "email" field which is the unique key for my records.
At some stage I have to change the key, so I do so, but it seems that after that a findOne with that new key fails:
var userObject = {"email" : "test123#gmail.com", ....}
var oldEmail = "tmp_email_123";
User.updateAsync({email: oldEmail},{$set : userObject))
.then (function( affected) {
User.findOneAsync({ 'email' : userObject.email}) <---- this returns null
})
However running against the db in the mongo console, shows the update was successful
db.users.find({"email":"test123#gmail.com"}) <---- returns the updated record.
Any clue why this might be happening?
I've been looking and deubgging this code for hours, with no clue.
Thanks!
D.

Resources