$push on the basis $cond in mongodb? - node.js

I have Review schema having likeBy array contains the id of the users who likes the review...
I have to query it like
case 1: If id exist the pull it.
case 2: If id does not exist then push it.
Is it possible to do in a single query???
Review Schema
{
"_id" : ObjectId("5aa0f4aeb5cbb2313276cccc"),
"__v" : 0,
"likeBy" : [ ]
}

This is how I would have done it
db.people.findAndModify({
query: { likedBy : {idOftheUserinLikedArray: "anyId" }},
$push: { likedBy : {idOftheUserinLikedArray: "anyId" } },
new : true
})
I am not sure if that's what you want. Let me know if that works for you.
What this will do is, if it finds that Review object against the property your are searching for in likedBy array property of the documents it will return you the updated object so you can check the likedBy array if the value is inserted or not.
May be helpful
And don't forget to give it a look

Related

Delete whole document for matching objectId in array of objects - MongoDB

The structure of my document looks like this in MongoDB :-
{
_id : "7464bbuiecdhbjdje"
client : "MJMK"
users : [
{_id : "1234" , name : "first user"}
]
}
I would like to remove the whole document for matching users._id. In this case, for a user with _id 1234,the whole document needs to be removed. I have been unable to find any efficient function that does this in Node using mongoose. Thanks for your help.
You want to use deleteMany.
This will delete all documents containing the matches query, in this case a user with matching _id in the users array. Our query will be utilizing Mongo's dot notation to access the array like so:
Model.deleteMany({ 'users._id': "1234" })
From the shell following works. Isn't it possible to do the same in node?
db.collectionname.find({ "users": { $elemMatch: { "_id": "1234" } } })
db.collectionname.remove({ "users": { $elemMatch: { "_id": "1234" } } })
Try this:
db.collectionName.remove({"users._id":{_id:"1234"}})

Updating multiple documents with mongoose not working

I have a Node/Express API using Mongoose, where I am trying to update subdocuments within multiple documents.
Essentially I have a user with a profile that has multiple phone numbers that they can share with another contact.
Each contact has a profile.contacts[] section, that has profile.contacts.phones[] section.
When the main user sharing his/her phone number with other users changes his/her number, I want to update the profile.contacts.phones[] section in all documents, where the _id of that phone number matches.
Here is my code:
Profile.update({'contacts.phones._id':req.body._id}, {
Profile.contacts.phones.phone_number:req,body.phone_number,
Profile.contacts.phones.phone_type:req.body.phone_type
}, {multi:true}, function(err, result){
if(err)
res.send(err)
res.json(result);
})
Here is a sample "Profile" document:
{
"_id" : ObjectId("59c09dca981de33d180df943"),
"last_name" : "Sam",
"first_name" : "Sam",
"owner_id" : "59c09dca981de33d180df940",
"contacts" : [
{
"first_name" : "Joe",
"last_name" : "Public",
"_id" : ObjectId("59c09dca981de33d180df944"),
"phones" : [
{
"phone_number" : "2067155803",
"phone_type" : "home",
"_id" : ObjectId("59bca0b55481370985cac29a")
}
]
}
]
"__v" : 0
}
Based on what I see in the documentation, this should work...
Thanks for any insight!!
I think you would need to use the positional operator to update an object in an array $ that matched the query.
However, this cannot be used for nested arrays:
The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.
https://docs.mongodb.com/manual/reference/operator/update/positional/
You might have to consider restructuring your documents.

Mongoose Model : get fields displayed in all the document while retrieving even if fields are missing in saved collection

Considering a collection, photo field is not defined in some documents. When I try to retrieve photo from the collection. I get the following response
{
"_id" : ObjectId("5757ea898a9d52801b98cc25"),
}
{
"_id" : ObjectId("5757ea898a934dsadsadsd25"),
"photo" : 'user.jpg'
}
Is there by chance I can get fields displayed in all the document even if it is missing (something like this)
{
"_id" : ObjectId("5757ea898a9d52801b98cc25"),
"photo": undefined
}
{
"_id" : ObjectId("5757ea898a934dsadsadsd25"),
"photo" : 'user.jpg'
}
Just required to add the default value to the key in the Schema definition. If data key is not available in the document, it returns the default value.

How to update one field if the document exist in a collection using mongodb and nodejs?

I am new dealing with mongodb, I read a set of identified documents from one source time to time. I save the documents to a collection using "_id" field to avoid repetition.
I want to add the documentos to the new documents, but if any documento exist, I want to update a field of the documento (in this case, increase a value like a counter).
I would to ask if there are a easy way to do this in mongodb.
Make of use upsert with update query.
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>
}
)
db.students.update(
{ "_id" : "1" },
{ "$set" : { "name" : "Hiren" } },
{ "upsert" : true }
);
if student with id 1 doesnot exists it will add new document with id 1 and name hiren. and if document exists with _id 1, then updates its name to Hiren.

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);

Resources