I am trying to insert embedded document in MongoDB through nodejs. This is schema of embedded document
var patientSchema = new mongoose.Schema({
status: {type: String},
message:{type: String},
statusCode:{type: Number},
user: [{
pname: {type : String },
email: {type : String },
password: {type : String },
mobile: {type : String},
otp:{type: Number},
age: {type : String }
}]
})
and here is the code of insertion
router.post('/panel/register', function(req, res){
console.log(req.body.mobile_number+req.body.email);
new patient({
status: "ok",
message:"success",
statusCode:"201",
'user.$.pname': req.body.name,
'user.$.password': req.body.password,
'user.$.email': req.body.email,
'user.$.mobile': req.body.mobile_number
}).save(function(err, doc){
if(err) res.json(err);
else {
res.json({"doc ":doc});
}
})
})
but whenever i am trying to insert data using this code it is showing me this error
{
"code": 11000,
"index": 0,
"errmsg": "E11000 duplicate key error index: rhc.patients.$mobile_1 dup key: { : null }",
"op": {
"status": "ok",
"message": "success",
"statusCode": 201,
"_id": "59f38e4d94fff613fc8c4979",
"user": [],
"__v": 0
}
}
As i am understanding this error is because this is not mapping the values of email, mobile inside the user, can someone help to resolve it, i think i am inserting it in wrong way , please help
Edit:
For clarity: the problem wasn't really the syntax, but rather a unique constraint that was removed, without the database being updated. You can read more about that here and here.
Original answer:
You can do it like this:
router.post('/panel/register', function(req, res){
console.log(req.body.mobile_number+req.body.email);
new patient({
status: "ok",
message:"success",
statusCode:"201",
user: [{
pname: req.body.name,
password: req.body.password,
email: req.body.email,
mobile: req.body.mobile_number
}]
}).save(function(err, doc){
if(err) res.json(err);
else {
res.json({"doc ":doc});
}
})
})
This will create a user object in the user array. Are you sure it's supposed to be an array on not just an object? Remove [] from both the model and controller to make it an ordinary object.
Related
I was trying to do an update operation. Now I'm getting an immutable error I knew the cause it was updating the key. I wonder because I'm not passing the _id from the API still I can see the _id if I console. I want to remove the _id from my object in order to fix this error. Code below
router.put('/:id', (req, res) => {
//var findid= req.params.id;
if (!ObjectId.isValid(req.params.id))
return res.status(400).send(`No record with given id : ${req.params.id}`);
var alum = new Alumni({
fname: req.body.fname,
lname: req.body.lname,
contact: req.body.contact,
gender: req.body.gender,
dob: req.body.dob,
message: req.body.message,
city: req.body.city,
pincode: req.body.pincode,
state: req.body.state,
district: req.body.district,
password: req.body.password,
email: req.body.email
});
//delete alum['_id'];
Alumni.findByIdAndUpdate(req.params.id, { $set: alum }, { new: true }, (err, doc) => {
if (!err) { res.send(doc); }
else {
console.log(alum);
console.log('Error in Alumni Update :' + JSON.stringify(err, undefined, 2)); }
});
});
How can I resolve this error?
Whenever JSON object is assigned using mongoose model like new Alumni(), by default it assigns _id field which is immutable so you don't need to use model with update object. Simply assign it as given below
var alum = {
fname: req.body.fname,
lname: req.body.lname,
contact: req.body.contact,
gender: req.body.gender,
dob: req.body.dob,
message: req.body.message,
city: req.body.city,
pincode: req.body.pincode,
state: req.body.state,
district: req.body.district,
password: req.body.password,
email: req.body.email
};
I'm building an Express/Node application and I'm trying build a login controller. When the request comes through to /login, I am able to find the user details in my Mongo collection with Mongoose' model.findOne, but the problem is that what the function returns is not all that is in the mongo document.
Querying the data through Robo 3T returns all the information
Here is my model
{
firstname: String,
surname: String,
fullname: String,
firthDate: Date,
identityType: String,
identityNumber: String,
address: {
residential: Object,
business: Object
},
contact: {
email: String,
cellphone: String,
home: String,
business: String,
fax: String
},
compliance: {
type: String,
value: String
},
account: {
type: String,
username: String,
password: String,
masala: String
},
created: Date,
updated: Date
}
Here is my controller:
user.findOne({"account.username": username}, (err, doc) => {
if (!err) {
// found user. Compare passwords and return JWT;
console.log(doc);
bcrypt.compare(password, doc.account.password, (err, isValid) => {
// I get an error here : Cannot read property password of undefined.
if (!err) {
if (isValid) {
// generate jwt and send back to user;
}
} else {
// invalid password provided;
}
});
} else {
}
});
I get an error: Cannot read property "password of undefined.
And this is the response that is in "doc" :
{
firstname: "hello",
surname: "world",
fullname: "hello world",
firthDate: "01 January 1970",
identityType: "idnumber",
identityNumber: "12345",
address: {
residential: {},
business: {}
},
contact: {
email: "",
cellphone: "",
home: "",
business: "",
fax: ""
},
compliance: {
type: "",
value: ""
}
}
It looks like the "doc.account" data is not returned as part of the response from the findOne function. I don't know why because I am using the data in the "doc.account" to search in the first place.
Your account schema is wrong.
For nested objects, it should be like this.
acount:{
username: {type:String},
password: {type:String},
}
Now this will be considered an object with properties username and password
I am new to MongoDb, and I have a question about the insertion of data. My mongoose schema for 'user' collection:
var user = new mongoose.Schema({
username : {type: String},
email : {type: String,index: {unique: true}},
password : {type: String},
feed : [{
title : {type: String},
description : {type: String},
latitude : {type:Number},
longitude : {type:Number},
feedImages : [{
imageUrl: {type: String}
}]
}]
});
I want to insert data to the feedimages and my service for that is:
app.post('/uploadFeedImage',function(req,res) {
var _id = req.body._id;
var imageUrl = req.body.imageUrl;
db.user.update(
{"feed._id":_id },
{$push : {
feedImages:{
imageUrl:imageUrl
}
}
},function (err,result) {
if (err) {
res.json({"success": '0', "message": "Error adding data"});
}
else {
res.json({"success": '1', "message": "Data added"});
}
});
});
But the data is not inserted into table and no error is shown, I don't know what is the problem.
My user table is shown below:
use $ to push in the matched element of the array. i.e. for which feed._id matches
Try this:
db.user.update(
{"feed._id":_id },
{$push : {
"feed.$.feedImages":{
imageUrl:imageUrl
}
}
},function (err,result) {
if (err) {
res.json({"success": '0', "message": "Error adding data"});
}
else {
res.json({"success": '1', "message": "Data added"});
}
});
Edit
$ is update positional operator, which helps update only the element which matches the update criteria. For more info see MongoDB $ operator Documentation.
I got a One-to-Many association error between(user 1<--->1..*robot) , I want to add a new document when a new user subscribe he should add a new robot with (reference and nom), so the user information should be add on the user collection as new document and the robot information should be add as a new collection on the robot collection in my mongodb database.
/routes/users.js :
router.post('/register', function(req, res, next) {
//tester si username exist
var user = new models.user({
nom_prenom: req.body.nom_prenom,
username: req.body.username,
password: req.body.password,
email: req.body.email,
sexe: req.body.sexe,
adresse: req.body.adresse,
admin: false
});
var robot = new models.robot({
reference: req.body.reference,
nom: req.body.nom,
flag: req.body.flag
});
user.save(function(err, u){
if(err) res.json(err);
res.json(u);
})
robot.save(function(err, u){
if(err) res.json(err);
res.json(u);
})
});
/models/users.js :
var mongoose = require('../config/db');
var UserSchema = mongoose.Schema({
nom_prenom: String,
password: String,
username: String,
email: String,
//username: { String, unique:true, required:true },
//email: { String, unique:true, required:true },
date_naissance: Date,
adresse: String,
sexe: String,
equipements:[{type: mongoose.Schema.Types.ObjectId, ref: 'Equipement'}],
robots:[{type: mongoose.Schema.Types.ObjectId, ref: 'Robot'}],
admin: Boolean
});
module.exports = mongoose.model('User', UserSchema);
/models/robot :
var mongoose = require('../config/db');
var RobotSchema = mongoose.Schema({
reference: String,
nom: String,
flag: Boolean,
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});
module.exports = mongoose.model('Robot', RobotSchema);
/routes/robots.js:
router.get('/', function(req, res, next){
models.robot.aggregate([
{
"$group": {
"_id": "$user_id",
"robots": { "$push": "$$ROOT" }
}
}
]).exec(function(err, results){
if (err) res.json({error: err});
models.user.populate(results, { "path": "_id" }, function(err, result) {
if(err) res.json({error: err});
console.log(result);
res.json(result);
});
});
});
the result Postman:
The Result on CMD after i execute :db.robots.find().pretty();
{
"_id" : ObjectId("57b5862673c11c840b31cc55"),
"reference" : "Rob9999",
"nom" : "Robot 9999",
"flag" : false,
"__v" : 0
}
and the result on CMD after I execute db.users.find().pretty();
{
"_id" : ObjectId("57b5862673c11c840b31cc54"),
"nom_prenom" : "test",
"username" : "test",
"password" : "test",
"email" : "test#orange.tn",
"sexe" : "femme",
"adresse" : "tunis",
"admin" : false,
"robots" : [ ],
"equipements" : [ ],
"__v" : 0
}
I don't find why the array robots in user is empty??
Can I do that insert a user and a robot that should appear in the list of robots of that user?
I think you didn't push newly created robot's _id to the robots array in user document while saving it.
Try This:
router.post('/register', function(req, res, next) {
//tester si username exist
var user = new models.user({
nom_prenom: req.body.nom_prenom,
username: req.body.username,
password: req.body.password,
email: req.body.email,
sexe: req.body.sexe,
adresse: req.body.adresse,
admin: false
});
var robot = new models.robot({
reference: req.body.reference,
nom: req.body.nom,
flag: req.body.flag
});
// dont change the header(res.json(u)) multiple times, make sure you set the header
// single time only. otherwise you may get unnecessary errors.
robot.save(function(err, u){
if(err) res.json(err);
//save user only after robot is successfully saved and push its id into robots array.
user.robots.push(u._id);
user.save(function(err, user){
if(err) res.json(err);
res.json(user);
return;
});
});
});
I've created a Mongoose Schema that looks like this:
var UserSchema = new Schema({
user: [{
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
index: { unique: true }
},
password: {
type: String,
required: true
},
mobile: Number
}],
account: [{
locked: {
type: Boolean,
default: false
},
accountType: {
type: String,
default: "guest"
},
failedLogins: {
type: Number,
default: 0
}
}],
reset: [{
resetToken: String,
resetExpirey: Date
}],
details: [{
accountCreated: Date,
lastLogin: Date
}]
});
As you can see I've tried to group certain fields. Is this the correct way to do it? I'm now having trouble referencing the fields. I get an error when I try this:
User.create({
user.name : req.body.name,
user.email : req.body.email,
user.password: req.body.password
}, function(err) {
if (err) res.send(err);
});
Error is unexpected token '.' in user.name
Your create statement still needs to be proper javascript, so your left-side object literals will need to be strings.
User.create({
'user.name' : req.body.name,
'user.email' : req.body.email,
'user.password': req.body.password
}, function(err) {
if (err) res.send(err);
});
Furthermore, because Mongoose requires you to have an array instead of allowing proper sub-objects, you'll need to actually insert these as an array.
var user = {user: [{name:req.body.name, email: req.body.email, password: req.body.password}]};
User.create(user) ...
As to the "is it worth it" to do it like this, my opinion is: no. Just put all these things in the root object unless you plan on having more than one user or more than one account in this one document.