MongoDB find then query nested document [duplicate] - mongodb

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 5 years ago.
I'm trying to make a 'like' route that find user by _id then query inside user.post an object id, so far I tried this:
User.find({
"_id": logged_user,
"posts_id": {
$elemMatch: req.body.id
}
}, (err, data) => {
if (err) {
res.json(err)
}
console.log(data);
})
Schema:
username: String,
posts:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
it returns an empty array '[]', how can I return true of false if it exists?

You are using $elemMatch wrong. It needs an object. Do it this way:
User.find({"_id":logged_user,"posts":{$elemMatch: {$eq : req.body.id}}},(err,data)=>{
if(err){
res.json(err)
}
console.log(data);
)

Related

How to return only the updated subdocument inside of array after an update [duplicate]

This question already has answers here:
Mongoose select fields to return from findOneAndUpdate
(7 answers)
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 3 years ago.
I have a user model with the following schema
{
_id: userId,
inbox: {
inbox: [Array of message documents],
sent: [Array of message documents],
}
}
Is there a way to get only the updated subdocument after an update in mongodb / mongoose ?
The update is good i just want to return the updated subdocument instead of querying the db again
db.getCollection("users").findOneAndUpdate(
{ "inbox.sent._id": ObjectId("5cea23be8c03c800d43a8376") },
{ "$set": { "inbox.sent.$.inTrash": false } },
{ "inbox.sent.$": 1 } <-- how to return only the subdocument like in a query
);
expected output the array at inbox.sent with only the updated doc
{
_id: userId,
inbox: {
sent: [{ updated doc}]
}
}
You need to apply a callback to the findOneAndUpdate function
e.g:
db.getCollection("users").findOneAndUpdate(
{ "inbox.sent._id": ObjectId("5cea23be8c03c800d43a8376") },
{ "$set": { "inbox.sent.$.inTrash": false } },
{ "inbox.sent.$": 1 },
function (err, res) {
//here you have the res, which will be the affected record
}
);

MongoDB update nested array of object by index [duplicate]

This question already has answers here:
Update field in exact element array in MongoDB
(5 answers)
Closed 5 years ago.
Let's suppose to there is db like below...
{ _id: 1234,
key: 'Contacts',
value: [
{ name: 'McDonald', phone: '1111'},
{ name: 'KFC', phone: '2222'}
]
}
And I want to change KFC's phone number to '3333'.
What I did is
DB.findOne({ key: 'Contacts' }, function(err, db){
db.value[1]['phone'] = '3333'
db.save(function(err, result){
// done
})
}
)
But it didn't update the database. What am I wrong?
There's no specific _id in elements of array for some reason.
Only the way to find specific element is index.
Use the positional operator $
more info : https://docs.mongodb.com/manual/reference/operator/update/positional/#up.S
DB.update({key: "Contacts", "value.name": "KFC" },
{ $set: { "value.$.phone" : 666 } },function(err,doc){
});

How to push stuff in the array inside another array in mongoose [duplicate]

This question already has answers here:
Mongodb $push in nested array
(4 answers)
Closed 5 years ago.
I have a User schema with a message field which looks like this:
messages: [{
receiver: {
type : Schema.Types.ObjectId,
ref: 'User'
},
history: [{
user: {
type : Schema.Types.ObjectId,
ref: 'User'
},
message: {
type: String
},
date: {
type: Date,
default: Date.now
}
}]
}]
I'm adding user in message array this way:
await User.update({_id: userID }, {$push: {"messages": {"$each" : [{user: friendID}]}}})
How could I add an object inside history array?
You will need to use the positional operator (<array>.$) to match the message you want to update and then $push to the history array within that message.
Note that as explained in the documentation:
The positional $ operator acts as a placeholder for the first element that matches the query document.
Therefore it might be useful to have an _id or some unique identifier for each message in your array. I didn't see something like that in your schema, though. If you use user, then it will match the first message with that user.
You code would therefore be something like:
User.update({
_id: userId,
"messages.<uniqueIdKey>": <uniqueIdValue>,
},
{
$push: {
"messages.$.history": <objectToPush>
},
});

mongoDB: check if value exists in specific subdocument array [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 5 years ago.
I have the following schema:
{
_id: objectID('593f8c591aa95154cfebe612'),
name: 'test'
businesses: [
{
_id: objectID('5967bd5f1aa9515fd9cdc87f'),
likes: [objectID('595796811aa9514c862033a1'), objectID('593f8c591ba95154cfebe790')]
}
{
_id: objectID('59579ff91aa9514f600cbba6'),
likes: [objectID('693f8c554aa95154cfebe146')]
}
]
}
How can I check if objectID('593f8c591ba95154cfebe790') exists in the array business.likes where businesses._id = objectID('59579ff91aa9514f600cbba6') ?
In the above example it should return false.
You can use $elemMatch to find by multiple field in same sub document
db.collectionName.find({
businesses: {
$elemMatch: {
_id: ObjectId("5967bd5f1aa9515fd9cdc87f"),
likes: ObjectId("593f8c591ba95154cfebe790")
}
}
});

Mongoose findOne and save new document [duplicate]

This question already has answers here:
pushing object into array schema in Mongoose
(2 answers)
Closed 6 years ago.
I have a list of users that has 'hobby' object inside it.
User: {
name: John Doe,
hobby: {
[{hobby_id: 77777, hobby_name: hockey, hobby_type: sports}],
[{hobby_id: 88977, hobby_name: singing, hobby_type: talent}],
}
age: 27
}
now i want to findOne the user and add new hobby on the list. my first try is:
var user = User.findOne({ _id : req.body.user_id});
User.update(user, { hobby: [{ hobby_name: req.body.name ,
hobby_type: req.body.type }] },
function(err, user){
if(err){
return res.status(500).json(err);
}else{
return res.status(200).json(user);
}
});
however, with this code, everytime i call the function, my "NEW" hobby replaces the first one.
what can i do?
You can use the following code to do the same.
User.findByIdAndUpdate(req.body.user_id, {$push:{ hobby: [{ hobby_name: req.body.name ,
hobby_type: req.body.type }] }}, {safe: true}
function(err, user){
if(err){
return res.status(500).json(err);
}else{
return res.status(200).json(user);
}
});
And here findByIdAndUpdate is do both finding and updating the same document. no need to use callback or promises. Please refer the following link.
Your problem is that you are using whe repalce syntax, rather than the update syntax. I think you need:
user.hobbies.push({ hobby_name: req.body.name ,
hobby_type: req.body.type })