Why pull is not removing elements - node.js

I have been trying to remove elements from the array, seem like it's not working, here is the model
1. Question Model
{
reviews: [{ type: ObjectID, ref: 'Review' }]
}
2. Review Model
{
description: {
type: String
},
userId: {
type: ObjectId,
ref: 'User'
}
}
And here is my service for the Quuestion.js
export const deleteReview = async ({ reviewId, id }, user) => {
try {
const result = await Question.updateOne(
{ _id: id },
{
$pull: { reviews: { _id: reviewId, userId: user._id } }
}
).exec();
if (result.nModified === 0) {
throw new APIError({ message: msg('Unauthorized'), status: 401 });
}
return result;
} catch (error) {
throw error;
}
};
Routes file
router.delete('/questions/:id/reviews/:reviewId', auth, async (req, res) => {
try {
const {
params,
user
} = req;
const data = await deleteReview( params,
user);
return res.status(200).json({ data });
} catch (err) {
error(res, err);
}
});
I was trying to remove the elements but it's not removing at all, I have no idea where I did a mistake.

Here is the solution I got, the $pull is not working so applied the $pullAll
export const deleteReview = async ({ reviewId, id }, user) => {
try {
const result = await Question.updateOne(
{ _id: id },
{
$pullAll: { reviews: [{ _id: reviewId, userId: user._id }] }
}
).exec();
if (result.nModified === 0) {
throw new APIError({ message: msg('Unauthorized'), status: 401 });
}
return result;
} catch (error) {
throw error;
}
};

Related

NodeJS, Mongoose prevent Push to write if same data is already in the array

I have app where I have Users. Every user can be an owner of an item or multiple items..
If user is already owner of that item prevent to push the item object into array, if already exists.
I already tried different solutions (I will write what I tried in the end of the question).
User model:
import * as mongoose from "mongoose";
const Schema = mongoose.Schema;
const UserSchema = new mongoose.Schema({
email: { type: String, required: true, min: 6, max: 255 },
password: { type: String, required: true, min: 4, max: 1024 },
role: { type: String, required: true, default: "User" },
owners: [
{
type: Schema.Types.ObjectId,
ref: "Owners",
required: false,
},
],
});
module.exports = mongoose.model("Users", UserSchema);
Add owner to user controller:
exports.addOwnerToUser = async (req: Request, res: Response) => {
try {
console.log("here");
let ObjectID = require("mongodb").ObjectID;
const mongoose = require("mongoose");
const user = {
email: req.body.email,
ownerId: req.body.ownerId,
};
const updatedUser = await User.findOneAndUpdate(
{
_id: req.params.userId,
owners: { $ne: req.body.ownerId },
},
{
$push: { owners: req.body.ownerId },
}
);
res.status(201).json({ sucess: true, msg: "User updated sucessfully" });
} catch (err) {
res.status(404).json(err);
}
};
I already tried solutions like this, but nothing works as expected.. (check the commented code)
exports.addOwnerToUser = async (req: Request, res: Response) => {
try {
console.log("here");
let ObjectID = require("mongodb").ObjectID;
const mongoose = require("mongoose");
// add get user and find if he already has this id.. if has then json 200
// if not i execute line 230
const user = {
email: req.body.email,
ownerId: req.body.ownerId,
};
/* const updatedUser = await User.findOneAndUpdate(
{ _id: req.params.userId },
{
"ownerId.ownerId": {
$ne: ObjectID(req.body.ownerId),
},
},
{
$addToSet: {
"ownerId.ownerId": ObjectID(req.body.ownerId),
},
},
{
new: true,
}
); */
const updatedUser = await User.findOneAndUpdate(
/* {
_id: req.params.userId,
},
{
$addToSet: {
owners: req.body.ownerId,
},
},
{
new: true,
} */
{
_id: req.params.userId,
owners: { $ne: req.body.ownerId },
},
{
$push: { owners: { ownerId: req.body.ownerId } },
}
);
console.log(updatedUser);
/* const updatedUser = await User.findOneAndUpdate(
{ _id: req.params.userId },
{
$push: { ownerId: { ownerId: req.body.ownerId } },
}
);
console.log(updatedUser); */
// $addToSet: { members: { name: 'something', username: 'something' } }
/*
User.findByIdAndUpdate(req.params.user_id,{$set:req.body},{new:true}, function(err, result){
if(err){
console.log(err);
}
console.log("RESULT: " + result);
res.send('Done')
});
};
*/
res.status(201).json({ sucess: true, msg: "User updated sucessfully" });
} catch (err) {
res.status(404).json(err);
}
};

to find total following and follower

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

how to find in an Array of Objects by id?

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

How to find top 10 most viewed and top 10 most liked data in mongoose

I have a Post table in mongo db. There are 1000 of post in the table. I tried following query to fetch top 10 most viewed and top 10 most liked post but I don't get any expected output. How to get that output, please help me.
This is my Post model in mongo db database where made two fields for views and likes.
const mongoose = require("mongoose");
const { Schema } = mongoose;
const postSchema = new Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
},
image: {
type: String,
},
likes: [User],
views: {
type: Number,
},
createdBy: {
type: Schema.Types.ObjectId,
ref: "users",
},
createdAt: {
type: Date,
default: Date.now,
},
});
//Controller
topViewPosts(req, res) {
try {
Post.find()
.sort({ views: -1 })
.limit(10)
.then((posts) => {
console.log(posts);
res.status(200).json({
message: "Fetch seccessful",
posts: posts,
});
})
.catch(() => {
res.status(500).json({
error: error,
});
});
} catch (error) {
res.status(500).json({
error: error,
});
}
},
topLikePosts(req, res) {
try {
Post.find()
.sort({ likes: -1 })
.limit(10)
.then((posts) => {
console.log(posts);
res.status(200).json({
message: "Fetch seccessful",
posts: posts,
});
})
.catch(() => {
res.status(500).json({
error: error,
});
});
} catch (error) {
res.status(500).json({
error: error,
});
}
},
use the sort property :
router.get("/yourrouter", async(req, res) => {
try {
const variable = await Modal.find()
.sort(function(a,b) {
if (a.likes > b.likes) return -1
if (a.likes < b.likes) return 1
return 0
})
res.status(200).json(post)
} catch (error) {
res.status(500).json(error)
}
});

mongodb won't delete an element from ObjectId array

My schema looks like the following:
const userSchema = new Schema({
...
followings: [
{
user:{
type: Schema.ObjectId,
ref: 'User'
},
}
],
followers: [
{
user:{
type: Schema.ObjectId,
ref: 'User'
},
}
],
}, {timestamps: true})
And I need to implement "unfollow" feature.
I am currently trying this:
try {
// check if your id doesn't match the id of the user you want to unfollow
if (user._id === current_id) {
return res.status(400).json({ error: 'You cannot unfollow yourself' })
}
// remove the id of the user you want to unfollow from following array
const query = {
_id: current_id
}
const update = {
$pull: { "followings": {"_id": user._id }}
}
const updated = User.update(query, update)
// remove your id from the followers array of the user you want to unfollow
const secondQuery = {
_id: user._id
}
const secondUpdate = {
$pull: { "followers": {"_id": current_id} }
}
const secondUpdated = User.update(secondQuery, secondUpdate)
if (!updated || !secondUpdated) {
return res.status(404).json({ error: 'Unable to unfollow that user' })
}
res.status(200).json({
update,
secondUpdate
})
}
catch (err) {
res.status(400).send({ error: err.message })
}
This gives status 200 and sends update & secondUpdate to the client,
but the actual object doesn't get deleted from the database.
What is wrong with my code?
If you are using mongodb native drive
You should import mongodb ObjectID. Before performing operations.
const ObjectId = require('mongodb').ObjectID;
$pull: { "followers": {"_id": current_id} }
change to:
$pull: { "followers": {"_id": new ObjectId(current_id) }
Thank you for your answers.
In my case, the following worked for me.
try {
// check if your id doesn't match the id of the user you want to unfollow
if (user._id === current_id) {
return res.status(400).json({ error: 'You cannot unfollow yourself' })
}
// remove the id of the user you want to unfollow from following array
const query = {
_id: current_id
}
const update = {
$pull: { followings: {_id: user._id }}
}
const updated = User.updateOne(query, update, {
safe: true
}, function(err, obj) {
console.log(err);
})
// remove your id from the followers array of the user you want to unfollow
const secondQuery = {
_id: user._id
}
const secondUpdate = {
$pull: { followers: {_id: current_id} }
}
console.log(secondQuery)
console.log(secondUpdate)
User.updateOne(secondQuery, secondUpdate, {
safe: true
}, function(err, obj) {
res.status(200).json({
obj
});
})
}
catch (err) {
res.status(400).json({ error: err.message })
}

Resources