Updating multiple documents in mongoose at once - node.js

I have an array of User documents each user has followers attribute which is a number, I just want to increment this attribute by 1 and then update all those user documents in the DB at once.
More details:
In the request I have an array of user ids, I query with those ids to get an array of user documents.
const users = await User.find({"_id": {$in: req.body.ids}});
each user document has an attribute called followers which is a number.
const userSchema = new mongoose.Schema({
// other attributes...........,
followers: {
type: Number,
default: 0
}
});
I want to increment the number of followers in each user in the users array and update the DB at once without sending a request to update each user separately, Is this even possible?
Thanks in advance

You can use $inc and run updateMany:
await User.updateMany({"_id": {$in: req.body.ids}}, { $inc: { followers: 1 } });

Related

How can I match all values nested in a collection to values in another collection (mongodb)?

I am creating a messaging app and I need to be able to display the users with which a given user has conversation history.
I have users and conversations. The models are below. (There is a messages collection where each document refers to a conversation)
//This is the conversation model.
const mongoose = require('mongoose');
const ConversationSchema = new mongoose.Schema({
participants: {
type: Array,
required: true
}
});
const Conversation = mongoose.model('Conversation', ConversationSchema);
//This is the users model (there's more to it, but this is the relevant stuff)
module.exports = Conversation;
const UserSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
}
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Each has an _id that is generated.
I am sending an http request with a user ID.
In my controller, using mongoose, I am able to do the following:
Conversation.find({participants:req.params.user_id})
This returns an array of conversation objects, each of which contains a participants array(an array of user IDs).
What I then need to do is match all the participants to the "users" collection so I can get the user ID, first name and last name of each user.
In summary, I need to send an HTTP request with a user ID as a parameter and receive an array of users which have conversation history with the provided user.
What is the next step? How can I match the user IDs I get from the relevant conversations to the user IDs in the users collection?
Try with this
app.post('/:user_id', async(req, res) => {
const partisipant = await Conversation.find({id:req.params.user_id});
const userData = await User.find({id:req.params.user_id});
if(!userData || userData != partisipant){
throw ('no data match')
}
//...if found the data, do anything you want
})
Using async await to get collection data from database, and compare them.
Hope this clue can help you

How to use model.findbyid and query inside it?

This is a simple question for you guys...I am wondering how can I acess a specific Id that is inside the "followers", after querying the User by its id. In other words i am searching for the user by its Id, and then I want to check the ids that are inside the followers.
For example: I have an Id saved in one variable "x", and I want to check if this Id "x" is inside of the followers array.
The model looks like this:
var UserSchema = new mongoose.Schema({
followers: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
]
});
module.exports = mongoose.model("User", UserSchema);
And the code that I am using is this one:
User.findById(req.params.id,'followers', function(err,name){
if(err){
console.log(err)
} else{
console.log(name);
}
});
It looks like I can print the user id and the id's that are inside the "followers", but i am not managing to see if the desired Id is inside of "followers" array or not.Can anyone help me with it?
Thank you for your attention!
I think you need to create nested for loop because you have an array of users according to user schema and each user has an array of followers and to solve this, you need to create for loop for user schema and inside that loop you will loop through all followers inside that user and check whether the id that you have equals to their id.
Since followers is an array of IDs (document references), if the query is for a single follower match you can use a shorthand of {followers: SOME_ID} or if it is an array then you can use {followers: {$all: [SOME_ID, SOME_OTHER_ID]}}. See the Mongo documentation for more information.
Using an array to match for example would look like the following.
User.findOne({_id: req.params.id, followers: {$all: [SOME_ID, SOME_OTHER_ID]}}, function(err, name) {
if (err) {
console.log(err)
} else {
console.log(name);
}
});

How to filter mongoose collection by Id node.js

Let's say I have a simple mongoose schema like this
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: String;
age: String,
created: { type: Date, default: Date.now }
})
module.exports = mongoose.model('User', UserSchema);
I can easily find all User collections with User.find({}). But I want to find only specified collections by their _id.
For example I have 10 user collections, and want to find only users according their Id in this dynamic array
["5b66c0868278664f0d2f2fec","5b66c5a947eaed565b694efa"]
so I am required to use where or match?
did you try $in?
User.find({_id : {$in : ["5b66c0868278664f0d2f2fec","5b66c5a947eaed565b694efa"]})
The $in operator selects the documents where the value of a field
equals any value in the specified array. To specify an $in expression,
use the following prototype:
User.find({ _id: { $in: ["5b66577c2f05bf1eb07956e0" ,"5b66b1879526eb0444d047cb"] }})
.then(users =>{
console.log("user", users)
})
Pass user id in postman parameter, then assign it to a variable then pass it to the function which is written for db activities. Then modal.findone(id);

How to use ref to store a document correctly in mongodb - mongoose?

I am trying to store a ref of a user model in my users - followers Array:
The model looks something like this:
User = require('../models/user.js');
ObjectId = mongoose.Schema.Types.ObjectId;
User = new Schema({
followers: [{ type: ObjectId, ref: 'User' }],
Now I am trying to store every time a user follows a user like so:
User.findByIdAndUpdate({_id: myId}, { $addToSet: {followers: user._id,
However, this only stores the string and not the whole user object? Is that how it is suppose to be? If so, then to grab it out the rest of the info do I just need to do a populate query?
If it is suppose to store the whole object then does it update as well as the object gets updated?
I was going to remove the question as I figured it out, but I see that people up-voted it so to help them out, I shall post my discoveries.
Apparently it will just store the id, and to then call it I used a basic populate call on it like so:
User
.findOne({ _id: myId })
.populate('followers', '_id name count') //
.exec(function (err, doc) {
if (err) return handleError(err);
})

Moogose complex query joins

I'm stuck with some complex query joins in mongoose (using nodejs)
I have the model User
{ active_payment: {type: mongoose.Schema.Types.ObjectId, ref: 'Payment'}}
And the model payment:
{status : Number, creation_date: Date}
I want to find all the users with the a paument of a status = 2.
I've tried:
User.find({'active_payment.status': 2,}).populate('active_payment')
But its not working. Is there any way to do it without having to sort all the users by a for loop?
I would also like to sort users by the creation_date of the payment.
You can not reach status in User.find() directly, Please try this one
User
.find({})
.populate({
path: 'active_payment',
match: { status: 2},
})
.exec(function(err, users) {
users = users.filter(function(user) {
return user.active_payment; // filter the user by active_payment field
});
});
With match to filter the status is 2 populate documents, then filter user after populate though active_payment.

Resources