update object inside array that is inside collection - node.js

I need to update field "rightAnswer" in object inside array that is inside collection.
How can I change boolean of specific comment to true for right question.
In Angular I pass id of question and id of comment to backend. But on the backend I don't know how to update that field. I use MEAN stack.
Question schema:
var questionSchema = new mongoose.Schema({
title: {type : String, default : '', trim : true},
text: {type : String, default : '', trim : true},
publisher_id: {type : mongoose.Schema.ObjectId, ref : 'User'},
answers: [{
body: { type : String, default : '' },
user: { type : mongoose.Schema.ObjectId, ref : 'User' },
rightAnswer: { type : Boolean, default: false },
createdAt: { type : Date, default : Date.now }
}],
date : {type : Date, default : Date.now}
});
My route in express:
Question.update({_id: req.body.question._id}, {"answers._id": req.body.answer._id}, {$set: {"answers.$.rightAnswer": true} }, function(req, data){
res.json(data);
});
Solution:
Question.update({_id: req.body.question._id,
"answers": {$elemMatch: {_id: req.body.answer._id}}},
{$set: {"answers.$.rightAnswer": true}},
function(req, res){});

Question.update({_id: req.body.question._id,
"answers": {$elemMatch: {_id: req.body.answer._id}}},
{$set: {"answers.$.rightAnswer": true}},
function(req, res){});

Related

how to update specific subdocument in array with mongoose

postSchema
let postSchema = new mongoose.Schema({
data : Buffer,
contentType : String,
caption : String,
likes : [mongoose.ObjectId],
likesCount : {type :Number, default : 0},
comment :[{userId :mongoose.ObjectId, cmnt : String, reply :[{}]}],
commentCount : {type :Number, default : 0},
date : {type : Date, default: Date.now}
})
userSchema
let userSchema = new mongoose.Schema({
qr : {
data : Buffer,
contentType : String
},
profile_pic:{
data:Buffer,
contentType : String
},
first_name:String,
last_name:String,
email:{
type:String,
unique:true
},
mobile_number:Number,
DOB : Date,
gender:{
type : String,
enum : ["Male","Female","Other"]
},
password : {
type : String
},
address:{
city : String,
state : String
},
followers : {
type : [mongoose.ObjectId]
},
followersCount : {
type : Number,
default : 0
},
following : {
type : [mongoose.ObjectId]
},
followingCount : {
type : Number,
default : 0
},
//this is my post schema
posts : [postSchema],
postsCount :{type :Number, default : 0},
reset_password_token : {
OTP:Number,
is_varify_password_token : {
type:Boolean,
default : false
},
time : {
type : Date,
}
}
})
** 1) i want to find specific user
2) after finding user i want to find and update specific post (caption) in array of posts **
i have tried but not working
await USERMODEL.findOneAndUpdate({_id:req.user._id,posts:{$elemMatch:{_id: req.params.postId}}},{"posts.$.caption ":caption})mongodb document image
PLEASE HELP I AM NEW TO MONGODB
**by mistake I have pasted some code out of block please do not mind **
It looks like your post is mostly code; please add some more details

Mongoose dup key

I'm getting a duplicate key error and not sure why.
I have the following schema:
var walletSchema = mongoose.Schema({
currencyName : {type : String, required : true, unique : true},
amount : {type : Number, default : 0}
}, {strict : false});
// define the schema for our user model
var userSchema = mongoose.Schema({
local : {
username : { type: String, required: true, unique: true },
password : { type: String, required: true, unique : true },
email : { type: String, required: true, unique: true },
country : { type: String, required: true },
inventory : {
food : { type : Number, default : 0},
energyDrinks : { type : Number, default : 0 }
},
wallet : [walletSchema],
lastAttackedAt : { type: Date, default: Date.now },
lastJobChange : {type: Date, default: '03/30/1988' },
lastWorked : {type: Date},
referredBy : {type : String, default : 'Admin'},
energy : { type: Number, default: 100 },
energyUpdatedAt : { type : Date, default: Date.now },
resetPasswordToken: String,
resetPasswordExpires: Date
}
},{timestamps : true});
I create a new user with this code :
...
newUser.local.username = capitalizeUser(username);
newUser.local.password = newUser.generateHash(password);
newUser.local.email = req.body.email;
newUser.local.country = req.body.country;
newUser.local.wallet.push({
// Create the default currencies
currencyName: 'Euro',
}, {
currencyName: 'Gold',
}, {
currencyName: result.countryCurrency
}
);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
Everything works fine for the first user however if I try to make another user I get MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: xyz.users.$local.wallet.currencyName_1 dup key: { : "Euro" }.
Why is this happening, doesn't each user has it's own wallet? How should I handle it, keep in mind that there are about ~230 currencies available for each user.
currencyName : {type : String, required : true}
Remove unique from there and you will be good to go. Mongo checks unique keys for collection. In your case walletSchema collection will have a lot of same values so that's why it's gives error.
As your currencyName has been set unique so it has to be different for each user you save. In fact you with this schema you won't even be able to have two users from the same country.
So to avoid this you need to remove the unique keyword from you schema and it is done. It then looks something like this.
var walletSchema = mongoose.Schema({
currencyName : {type : String, required : true},
amount : {type : Number, default : 0}
}, {strict : false});

Node.js - Create Relationships with Mongoose from different file

I have two Schemas Products and Users in different files. Products are belong to User and User have many Product
The Problem is, I have try to use Populate but somehow it return not what I expected.
here is my Schema for Product on models products.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var users = require('../models/users');
var Product = mongoose.Schema({
user_id : {type: String, required: true },
category_id : {type: String, default: null},
title : {type: String, required: true },
content : {type: String, default : "" },
pictureUrls : Array,
counter : {type : Number, default : 0},,
lowercaseTitle : {type: String, default : null },
_user : { type: Schema.Types.ObjectId, ref: users.User }
});
Product.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('Product', Product)
and this is my Schema for User on models users.js
var mongoose = require('mongoose');
var User = mongoose.Schema({
firstName : {type: String, default: "" },
lastName : {type: String, default: "" },
username : {type: String, required: true },
email : {type: String, required: true },
password : {type: String, default: "" },
bio : {type: String, default: "" },
website : {type: String, default: "" },
phone : {type: String, default: "" },
gender : {type: String, default: "" },
birthDate : {type: Date, default: null },
avatarUrl : {type: String, default: "" },
verified : {type : Boolean, default : false}
});
User.set('toObject', {
getters: true,
virtuals: true
});
module.exports = mongoose.model('User', User);
currently I am using method find by calling each Models
User.findOne({"sessionToken" : bearerHeader}, function (err, user){
Product.find({"user_id" : user._id}, function (err, products){
console.log(products);
});
});
but it takes time and became problem if there related to another models.
I'm calling populte with this
Product.findOne({}).populate('_user').exec(function(err, p){
console.log(p);
});
but attribute _user was not set and undefined
any help?
Thanks

mongoose: update field, push object in array [duplicate]

This question already has answers here:
Stop Mongoose from creating _id property for sub-document array items
(7 answers)
Closed 7 years ago.
I would like to add an element in an array in a mongo database:
db.keypairs.update( {pubkey: "1234567890"}, { $push: {listTxId: {txHash: "yyy", spent: false} } } )
The result is perfect:
listTxId" : [ { "txHash" : "xxx", "spent" : true },{ "txHash" : "yyy", "spent" : false } ]
Now I would like to do the same with node.js and mongoose
var res = wait.forMethod(Keypair,'update', {pubkey: "1234567890"}, { $push: { "listTxId": {"txHash":"zzz", "spent":false} } } );
Keypair is my node.js model for the mongoose collection:
var Keypair = require('./app/models/Keypair');
and wait.forMethod comes from a node module:
var wait = require('wait.for');
In the result, I have this "_id" element :
{ "txHash" : "zzz", "spent" : false, "_id" : ObjectId("56561571fea5d9a10a5771fd") }
QUESTION: where this ObjectId come from ? How can I get rid of it ?
UPDATE: mongoose schema:
var keypairSchema = mongoose.Schema({
userId : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
pubkey : String,
privkeyWIF : String, // temp
balance : Number,
listTxId : [{
txHash : String,
spent : Boolean
}],
walletId : { type: mongoose.Schema.Types.ObjectId, ref: 'Wallet' },
description : { type: String, maxlength: 40 },
comments : String,
isMasterKey : { type: Boolean, default: false },
date : Date
});
Mongoose will put ids in your subdocument arrays. listTxId is a subdocument array. You can add _id: false to your schema to prevent this:
var keypairSchema = mongoose.Schema({
userId : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
pubkey : String,
privkeyWIF : String, // temp
balance : Number,
listTxId : [{
_id: false,
txHash : String,
spent : Boolean
}],
walletId : { type: mongoose.Schema.Types.ObjectId, ref: 'Wallet' },
description : { type: String, maxlength: 40 },
comments : String,
isMasterKey : { type: Boolean, default: false },
date : Date
});

Mongoose - Query returns nothing

I have the following query:
app.get('/matches/:latMin/:latMax/:lonMin/:lonMax', function(req, res){
var matches = City.find({
"latitude": {$gt : String(req.param.latMin), $lt : String(req.params.latMax) },
"longitude" : {$gt : String(req.param.lonMin), $lt : String(req.param.lonMax)}
});
matches.exec(function(err, match){
if(err){
console.log(err);
return res.send(err);
}
console.log(match);
res.json(match);
});
});
Here is my schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('City', new Schema({
zip : {type : String, default: ''},
latitude : {type : String, default: ''},
longitude : {type: String, default: ''},
city : {type: String, default: ''},
state : {type: String, default: ''},
county : {type: String, default: ''}
}), 'locations');
When I run the query in the Mongo shell, the expected results are sent. However, the log in the above quotes returns []. Is there something wrong I'm doing here?
I don't know if you want to use req.param or it is just a typo. Anyway, req.param is deprecated and you should use req.params.
I have set up your scenario and queries are working. Replace the var matches in your code for the following:
var matches = City.find({
"latitude": {$gt : String(req.params.latMin), $lt : String(req.params.latMax) },
"longitude" : {$gt : String(req.params.lonMin), $lt : String(req.params.lonMax)}
});

Resources