I got it to work on accident with out adding a res.json(doc) but I found that when I make a POST request I need to send a response and ever since I added that response I get 0 or null?
add: function(req, res) {
//var newPlayer = new models.Team({ _id: req.params.tid }, { players: req.body });
models.Team.update({ _id: req.params.tid }, { $addToSet: { players: req.body} }, function(err, newPlayer){
if (err) {
res.json({error: 'Error.'});
} else {
res.json(newPlayer);
}
});
},
Also tried with findOneAndUpdate but my POST request is showing 0 or null for the response.
I am updating an array of objects inside a collection, it's nested. Here is the SCHEMA just to be clear.
var Team = new Schema({
team_name: { type: String },
players: [
{
player_name: { type: String },
points: { type: Number },
made_one: { type: Number },
made_two: { type: Number },
made_three: { type: Number },
missed_one: { type: Number },
missed_two: { type: Number },
missed_three: { type: Number },
percentage: { type: Number },
assists: { type: Number },
rebounds: { type: Number },
steals: { type: Number },
blocks: { type: Number },
fouls: { type: Number },
feed: { type: String },
facebook_id: { type: Number }
}
]
});
So my question is does anyone have any idea why I am getting that response 0?
The update method does not return the document in the response. The callback arguments are (err, numAffected) where numAffected is the number of documents touched by the "update" statement, which can possibly do "bulk" ( or multi ) processing.
What you want is findByIdAndUpdate() or findOneAndUpdate(). These methods return the either the original document or the modified document, according to the arguments you give.
add: function(req, res) {
models.Team.findByIdAndUpdate(
req.params.tid,
{ $addToSet: { players: req.body } },
function(err, newPlayer){
if (err) {
res.json({error: 'Error.'});
} else {
res.json(newPlayer);
}
}
);
},
Related
Here's my MongoDB post model that I am using with node.js.I want to update the number of likes under each object in comments array i.e number of likes on each comment.How can I increment the number of likes value.
_postid:6045b7a3b0b0423790d6484b
photo:Object
likes:Array
text:"hey there"
comments:Array
0:Object
1:Object
2:Object
_id :6045c9251f99b81ee4dbc0f6
text:"tetstst"
postedBy:6045c36dd8df2f2f00b115d5
likes:0
created:2021-03-08T06:50:13.851+00:00
created:2021-03-08T05:35:31.524+00:00
postedBy:6045116e37280f0970cf63a5
here's what I am trying to do using FindoneandUpdate:
Post.findOneAndUpdate(
model,
{ $inc: { "comments.likes": 1 } },
{ new: true }
).exec((err, result) => {
if (err) {
return res.status(400).json({
error: err,
});
}
res.json(result);
});
};
Here's my post schema that I am using:
text: {
type: String,
required: "Name is required",
},
photo: {
data: Buffer,
contentType: String,
},
likes: [{ type: mongoose.Schema.ObjectId, ref: "User" }],
comments: [
{
text: String,
created: { type: Date, default: Date.now },
postedBy: { type: mongoose.Schema.ObjectId, ref: "User" },
likes: Number,
},
],
If you want to increment the likes for each comment by 1, (I assumed here model to be your query object.)
Post.findOneAndUpdate(
model,
{ $inc: { "comments.$[].likes" : 1 } },
{ new: true }
).exec((err, result) => {
if (err) {
return res.status(400).json({
error: err,
});
}
res.json(result);
});
};
If you want to increment only the first comment in the post,
Post.findOneAndUpdate(
model,
{ $inc: { "comments.0.likes" : 1 } },
{ new: true }
).exec((err, result) => {
if (err) {
return res.status(400).json({
error: err,
});
}
res.json(result);
});
};
If you want to increment likes for a comment posted By 6045c36dd8df2f2f00b115d5
Post.findOneAndUpdate(
{ ...model, { "comments.postedBy": 6045c36dd8df2f2f00b115d5 }},
{ $inc: { "comments.$.likes" : 1 } },
{ new: true }
).exec((err, result) => {
if (err) {
return res.status(400).json({
error: err,
});
}
res.json(result);
});
};
Also Ref: https://docs.mongodb.com/manual/reference/operator/update-array/
Enroll.updateOne(
{
"reviewers._id": userID,
},
{
$set: {
"reviewers.$.scores": req.body.scores,
},
},
(errUpdate, resultUpdate) => {
if (errUpdate) {
return res.status(500).json({ success: false, error: errUpdate });
} else {
return res.status(200).json({ success: true, data: resultUpdate });
}
}
);
I'm new to mongodb. Above is a function within an api that is used to update certain data.
The schema of Enroll would look like this:
[
{
_id: xxxxx,
otherdata: xxxx,
reviewers: [ { _id: xxxx, otherdata: xxxx } , { _id: xxxx2, otherdata: xxxx2 } ]
},
{
second enroll item...
}
]
but when I called the api, it returns n:0 which indicates no match is found. Am I missing some steps here?
I am trying to make a report function for my app
in the front end I make a put request :
.put(`http://localhost:3000/api/posts/report`, {
params: {
id: mongoId,
reportInfo: {
reported: true,
reportingUser: id
}
}
})
to this backend route
router.put('/report', (req, res, next) => {
postModel.findOneAndUpdate(
{ _id: mongoose.Types.ObjectId(req.query.id) },
req.query,
{ new: true, useFindAndModify: false },
(error, returnedDocuments) => {
if (error) return next(error);
res.json(returnedDocuments);
}
);
});
for this model
const postSchema = new mongoose.Schema(
{
title: { type: String },
description: { type: String },
image: { type: String },
price: { type: String },
location: { type: String },
image: { type: Array },
author: {
type: String,
ref: 'User'
},
reportInfo: {
reported:{
type: Boolean,
default: false
},
reportingUser:{
type: String
}
}
},
{
timestamps: true
}
);
any ideas why it is not updating the reportInfo object , do I need to do something if there are some nested objects contained?
thanks
Your code tries to replace entires MongoDB document. Try to use $set instead of passing req.query directly:
{ $set: { reportInfo: req.query.reportInfo } }
I would also check if there should be req.query or req.body so just print the value to make sure that it gets deserialized properly.
router.delete('/deletepost', (req, res) => {
// console.log(req.query.postid)
if (req.query.category === 'forsale') {
ForSalePosts.findById(req.query.postid)
// .then(post => console.log(post))
.deleteOne()
.catch(err => console.log(err))
AllPosts.updateOne({ user: req.query.userid },
{ $pull: { posts: { postid: req.query.postid } } })
.catch(err => console.log(err))
AllPosts.aggregate(
[
{ $match: { user: ObjectId(req.query.userid) } },
{ $unwind: '$posts' },
{ $sort: { 'posts.date': -1 } }
]
)
.then(posts => {
// console.log(posts)
res.json(posts)
})
.catch(err => res.status(404).json({ nopostfound: 'There is no posts' }))
}
})
this is my route. i am trying to delete an item in my document. the item is being deleted however it returns old values. for example :
Allposts has an array with posts:[postid:{type:String}, ...]
I am trying to delete a specific postid by using $pull,
postid is being deleted however when I aggregate the same model, .then(posts=> console.log(posts)) returns old values on first call, doesnt update the component.
EDIT: just realized sometimes it returns the right values but sometimes it returns the old values as well. does anyone know why and what can i do to solve it ?
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
const AllPostsSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
posts: [{
postid: {
type: String
},
title: {
type: String
},
category: {
type: String
},
subcategory: {
type: String
}, category: {
type: String
},
description: {
type: String
},
name: {
type: String
},
price: {
type: Number
},
email: {
type: String
},
phonenumber: {
type: Number
},
language: {
type: String
},
make: {
type: String
},
model: {
type: Number
},
odometer: {
type: Number
},
condition: {
type: String
},
state: {
type: String
},
town: {
type: String
},
city: {
type: String
},
links: [{ type: String }],
date: {
type: Date,
default: Date.now
}
}]
})
module.exports = AllPosts = mongoose.model('allposts', AllPostsSchema)
REACT FUNCTION CALL :
deletePost = (category, postid) => {
const postinfo = {
category: category.toLowerCase(),
postid: postid,
userid: this.props.auth.user.id
}
this.props.deletePost(postinfo)
}
You need to add options parameter to delete like:
AllPosts.updateOne({ user: req.query.userid },
{
$pull: { posts: { postid: req.query.postid } }
},
{ new: true }
);
This will return the new object after performing the operation. Hope this works for you.
All the mongo queries return partial promise. You have to use .then in order to resolve each promises.
Here you are running all the queries in series without using .then or async-await. So whenever you $pull from AllPosts after that immediately you call the AllPosts aggregate query which sometimes get executed and sometimes it doesn't.
So in order to make it run one by one you have to use either .then or async-await.
router.delete("/deletepost", (req, res) => {
if (req.query.category === "forsale") {
ForSalePosts.findById(req.query.postid)
.deleteOne()
.then(() => {
AllPosts.updateOne(
{ "user": req.query.userid },
{ "$pull": { "posts": { "postid": req.query.postid } } }
)
.then(() => {
AllPosts.aggregate([
{ "$match": { "user": ObjectId(req.query.userid) } },
{ "$unwind": "$posts" },
{ "$sort": { "posts.date": -1 } }
]).then(posts => {
// console.log(posts)
res.json(posts);
});
})
.catch(err =>
res.status(404).json({ "nopostfound": "There is no posts" })
);
});
}
})
I'm trying to get the userid, and the array object that contains the specific location within locations.
What I want to accomplish is the following:
The query will return the array location's result.
If not userid exist at all, create it, then return the array of the matching location.
If the location id Number is not there. create a new one, then return the array of the matching location.
How can I accomplish this?
Current query:
easyCrime.findOne({
userid: userid,
"locations.location": location
}, {"locations.$.location": 1}).then(function (err, stats) {
}
});
model:
userid: {
type: String,
default: '57c1c0f3b6b20c011242bf22'
},
locations: [
{
userid: {
type: String,
default: '57c1c0f3b6b20c011242bf22'
},
location: {
type: Number,
default: 1
},
easycrime: [
{
optioname : {
type: String,
default: 'unknown'
},
chance: {
type: Number,
default: 500
}
}
],
heavycrime: [
{
optioname : {
type: String,
default: 'unknown'
},
chance: {
type: Number,
default: 500
}
}
],
}
],
timesteal: {
type:Number,
default: 0
}
I presume that easyCrime is Model, cause there is no such thing as findOne query in a Document. If it is a Model please name it EasyCrime.
I had a really hard time interpreting your question. Base on what I understand, this is your solution
EasyCrime
.findOne({ userid: param.userid})
.exec((err, crime) => {
//userid not exists at all, create new
if (!crime) {
let newCrime = new EasyCrime({...});
newCrime.save(...);
return;
}
//Check if location exists
for (let i = 0; i < crime.locations.length; ++i) {
if (crime.locations[i].location === param.location) {
//crime.location[i] is what you're finding
return;
}
}
//Cannot find any location with provided param.location
crime.locations.push({
userid: ...,
location: param.location,
...
});
crime.save(...);
})