Why this won't insert 20 document for me?
for (let i = 0; i <= 20; i++) {
const [updated] = await Promise.all([
Job.findOneAndUpdate(
{ _id: id },
{
$set: {
status: 'something'
}
},
{ upsert: true, new: true }
),
User.findOneAndUpdate(
{ _id: userId },
{
$set: { assigned: true }
},
{ upsert: true, new: true }
)
])
}
or I should use reduce and Promise resolve? Above query worked just that it doesn't insert 20 documents, it inserted one document.
If you have array of id then you can use bulkWrite
const id = ['844646464', '45646546546', '45646546546']
Model.bulkWrite(
req.body.idArray((id) => {
return ({
updateOne: {
filter: { _id: id },
update: { $set: { status: 'something' } },
upsert: true
}
})
})
})
It will create a request something like this
bulkWrite([
{ updateOne: { filter: { _id: id }, update: { $set: { status: 'something' } } },
{ updateOne: { filter: { _id: id }, update: { $set: { status: 'something' } } },
{ updateOne: { filter: { _id: id }, update: { $set: { status: 'something' } } }
])
Which efficiently performs all updates in a single request to the server with a single response.
Related
export const add_followers = async (req: Request, res: Response) => {
reqInfo(req)
let user: any = req.header('user'),
body = req.body,
response: any
console.log("user", user);
try {
response = await userModel.findOne({
_id: ObjectId(body.id), isActive: true, "follow.followers": { $elemMatch: { followedBy: ObjectId(user?._id) } }
}) // body.id -> jene follow karvanu 6 // user.id je follow kare 6
console.log("response", response);
if (response) {
console.log("response cond 1")
let data = await userModel.findOneAndUpdate({ _id: ObjectId(body.id), isActive: true }, {
$pull: { "follow.followers": { followedBy: ObjectId(user._id) } }
}, { new: true })
data = await userModel.findOneAndUpdate({ _id: ObjectId(user._id), isActive: true }, {
$pull: { "follow.following": { followingBy: ObjectId(body.id) } }
}, { new: true })
return res.status(200).json(await apiResponse(200, "unFollow Successfully", data, {}));
}
if (!response) {
console.log("response cond 2")
response = await userModel.findOneAndUpdate({ _id: ObjectId(body.id), isActive: true }, {
$push: {
"follow.followers": {
followedBy: ObjectId(user?._id),
name: user?.userName,
image: user?.userImage
},
$count: "follow.followers"
},
}, { new: true })
await userModel.findOneAndUpdate({ _id: ObjectId(user._id), isActive: true }, {
$addToSet: {
"follow.following": {
followingBy: ObjectId(body.id),
name: body?.userName,
image: body?.userImage
},
$count: "follow.following"
},
}, { new: true })
return res.status(200).json(await apiResponse(200, responseMessage?.addDataSuccess("following"), response, {}));
} else {
return res.status(403).json(await apiResponse(403, responseMessage?.getDataNotFound("user"), null, {}))
}
} catch (error) {
console.log(error)
return res.status(500).json(await apiResponse(500, responseMessage?.internalServerError, {}, error))
}
}
i want to get totalfollower and following in this user can follow complete but did'nt get total number of follower
Essentially, I am trying to update the winner's points and remove points from the losers, but for some reason, the connection closes before the loop finishes. Any help would be greatly appreciated!
module.exports.PointDistrubtion = async (winnerId, price, buyIn, losersId) => {
return await mongo().then(async (mongoose) => {
try {
await profileSchema
.findOneAndUpdate(
{
userId: winnerId,
},
{
$inc: {
Points: price - buyIn,
},
},
{
upsert: true,
new: true,
}
)
.then(
losersId.forEach(async (userId) => {
await profileSchema.findOneAndUpdate(
{
userId,
},
{
$inc: {
Points: -BuyIn,
},
},
{
upsert: true,
new: true,
}
);
})
);
} finally {
mongoose.connection.close();
}
});
};
Doing this should work:
module.exports.PointDistrubtion = async (winnerId, price, buyIn, losersId) => {
return await mongo().then(async (mongoose) => {
try {
await profileSchema.findOneAndUpdate(
{
userId: winnerId,
},
{
$inc: {
Points: price - buyIn,
},
},
{
upsert: true,
new: true,
},
);
await Promise.all(
losersId.map(async (userId) => {
await profileSchema.findOneAndUpdate(
{
userId,
},
{
$inc: {
Points: -BuyIn,
},
},
{
upsert: true,
new: true,
},
);
}),
);
} finally {
mongoose.connection.close();
}
});
};
I want to use mongoose to find in an array of objects by id.
I have this list:
{
"data":[
{
"_id":"60ce0ea7eb945a22288fd0ba",
"parent":"50ce0e44eb945a22288fd0b1",
"label":"label 1-2",
"ancestors":[
{
"_id":"50ce0e44eb945a22288fd0b1",
"label":"label 1-1"
},
{
"_id":"40ce077e90c6262bdc21aa44",
"label":"label 1"
}
]
},
{
"_id":"50ce0e44eb945a22288fd0b1",
"parent":"60ce077e90c6262bdc21aa55",
"label":"label 1-1",
"ancestors":[
{
"_id":"40ce077e90c6262bdc21aa44",
"label":"label 1"
}
]
},
{
"_id":"40ce077e90c6262bdc21aa44",
"parent":null,
"label":"label 1",
"ancestors":[]
}
]
}
This is the schema:
const categorySchema = new mongoose.Schema(
{
label: {
type: String,
required: true
},
parent: {
type: ObjectId,
default: null,
ref: 'category'
},
ancestors: [
{
_id: {
type: ObjectId,
ref: 'category'
},
label: String
}
]
},
{ timestamps: true }
);
I tried to do this:
async getDescendants(req, res) {
let { pId } = req.body;
if (!pId) {
return res.json({ error: 'All filled must be required' });
} else {
try {
const data = await patternModel
.find({ 'ancestors._id': pId })
.select({
_id: false,
label: true
})
.exec();
if (data) {
return res.json({ data });
}
} catch (err) {
return res.json({ err: err });
}
}
}
this is my actual result:
{
"data": []
}
when I change .find({ 'ancestors._id': pId }) to .find({ 'ancestors.label': label }) it works but not for the id.
It is not a simple field. It is an array of subdocuments. Use elemMatch.
Edit: When querying _id fields you will have to wrap convert them into ObjectIds (specific to Mongo).
let newPid = mongoose.Types.ObjectId(pId);
const data = await patternModel.find({ ancestors: { $elemMatch : { _id: newPid} } })
.select({ _id: false,label: true })
.exec();
Here is my Schema
I am trying to add replies array inside answers array. If someone answers a question and if someone wants to reply on the given answer
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const questionSchema = new mongoose.Schema(
{
postedBy: {
type: ObjectId,
required: true,
ref: "User",
},
question: {
type: String,
required: true,
},
photo: {
data: String,
required: false,
},
answers: [
{
userId: { type: ObjectId, ref: "User" },
answerType: {
data: String,
required: false,
},
answer: String,
replies: [
{
userId: { type: ObjectId, ref: "User" },
reply: String,
replyType: {
data: String,
required: false,
},
},
],
},
],
questionType: {
data: String,
required: false,
},
createdAt: {
type: Date,
required: true,
default: Date.now,
},
},
{ timeStamps: true }
);
module.exports = mongoose.model("Question", questionSchema);
Here is my Controller method
exports.postReply = (req, res) => {
const reply = req.body.reply || "";
const userId = req.user._id || "";
const answerId = req.body.answerId || "";
Question.findByIdAndUpdate(
{ _id: answerId },
({ $push: { answers: { answer: { replies: { reply, userId } } } } },
{ new: true }),
(err, newReply) => {
if (err) {
res.status(400).json({
error: errorHandler(err),
});
} else {
res.json({
msg: "Reply posted successfully",
newReply,
});
}
}
);
};
I feel I am going wrong on the findOneAndUpdate method. I am getting no error on the console but newReply comes null. Any help will be appreciated.
I would suggest you using the $addToSet instead of the $push operator as you are adding a document to the array. (see: https://docs.mongodb.com/manual/reference/operator/update/addToSet/).
If you want to add more than one document to the array, refer also to the $each operator together with $addToSet.
So your coding can look similiar to this (note: the variable 'yourDocument' is the document you want to add):
Question.findByIdAndUpdate(
{ _id: answerId },
{ $addToSet: { answers: yourDocument } },
{ new: true },
(err, newReply) => {
if (err) {
res.status(400).json({
error: errorHandler(err),
});
} else {
res.json({
msg: "Reply posted successfully",
newReply,
});
}
}
);
};
The problem is clearly the parentesis around
({ $push: { answers: { answer: { replies: { reply, userId } } } } }, { new: true })
Doing this console.log( ({a:1}, {b:2}) ); will log {b: 2} which means you are doing this
Question.findByIdAndUpdate( { _id: answerId }, { new: true }, (err, newReply) => {
So remove the parentesis and you should be good
Question.findByIdAndUpdate(
{ _id: answerId },
{ $push: { answers: { answer: { replies: { reply, userId } } } } },
{ new: true },
(err, newReply) => {
if (err) {
res.status(400).json({
error: errorHandler(err),
});
} else {
res.json({
msg: "Reply posted successfully",
newReply,
});
}
}
);
app.post("/admin/editAssignedTask/:id", (req, res) => {
Task.findById(req.params.id, (err, task) => {
task.title = req.body.title;
task.priority = req.body.priority;
task.date = new Date(req.body.date);
task.description = req.body.description;
if (req.body.assignTo) {
console.log(req.body.assignTo);
if (typeof req.body.assignTo == "string") {
task.assignedTo = [...task.assignedTo, req.body.assignTo];
Staff.find({ _id: req.body.assignTo }, (err, staff) => {
console.log(staff);
});
Staff.updateOne(
{ _id: req.body.assignTo },
{ $set: { $push: { todo: req.params.id } } },
(err, up) => {
console.log(up);
}
);
in the above code staff.find() returns
[ { todo: [ 5cc44b02abde080691893e41, 5cc46186db0195071f117808 ],
completed: [],
_id: 5cc34724ab9d2d231642f925,
name: 'gokul',
mailId: 'gokul',
__v: 12 } ]
but staff.updateOne() returns
{ ok: 0, n: 0, nModified: 0 }
here n is 0 which means no obects are matched.!
Why does this happen?
below is the Staff schema
var userSchema = new mongoose.Schema({
name: String,
mailId: String,
todo: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Task"
}
],
completed: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Task"
}
]
});
change
Staff.updateOne(
{ _id: req.body.assignTo },
{ $set: { $push: { todo: req.params.id } } },
(err, up) => {
console.log(up);
}
);
to
Staff.updateMany(
{ _id: { $in: req.body.assignTo } },
{ $push: { todo: mongoose.Types.ObjectId(req.params.id) } },
(err, up) => {
console.log(up);
}
);
1) don't use $set for pushing or pulling array elements.
2) since in the schema, attribute 'todo' is an array of objectIDs and not strings, we need to explicitly convert the string to objectIDs using mongoose.Types.ObjectId()