How to add data to array in Mongoose Schema - node.js

Assuming the following schema, I am trying to save some GeoJSON data with Mongoose
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : String,
coordinates : [ Number , Number ]
}
});
This is how I try to save the document
var a = new simple({properties:{name:"a", surname:"b"}, location:{type:"Point", coordinates:[1, 0]}}).save(function(err){...});
However, what I am getting in the database is
ObjectId("542da9ab0882b41855ac3be0"), "properties" : { "name" : "a", "surname" : "b" }, "__v" : 0 }
It looks like the whole location tag and data are missing. Is this a wrong way to define a schema or a wrong way of saving the document?

When using a field named type in an embedded object, you need to use an object to define its type or Mongoose thinks you're defining the type of object itself.
So change your schema definition to:
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : { type: String },
coordinates : [ Number , Number ]
}
});

Related

console.logging data from MongoDB

I am still trying to comprehend Mongoose/Mongo
Now in terminal When I do something like this in terminal
use library
show collections
db.authors.find().pretty()
I get something like this in logged
{
"_id" : ObjectId("5bc8704f3a9828d5513505a2"),
"name" : "Aman",
"age" : "21",
"__v" : 0
}
{
"_id" : ObjectId("5bc870553a9828d5513505a3"),
"name" : "Rohit",
"age" : "20",
"__v" : 0
}
{
"_id" : ObjectId("5bc8704f3a9828d5513505a7"),
"name" : "Aman",
"age" : "21",
"__v" : 0
}
{
"_id" : ObjectId("5bc870553a9828d5513505a5"),
"name" : "Rohit",
"age" : "20",
"__v" : 0
}
Now, I want to have same data in my NodeJs i.e say, I want to find wherever the name is Rohit and want to link it with with some other db or schema.
how can I get the same output which I just obtained by running the above given command in terminal window of mongo in NodeJS
Obviously doing something like this console.log(db.authors.find()) won't work, so how can I get that?
This is how I usually write my database queries.
First create a schema that your model will follow. Don't worry this schema is flexible and you can change it at any time without affecting old data.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var authorSchema = new Schema({
name: {
type: String,
required: true
},
age: {
type: Number,
default: 20
}
});
Next create a model from your schema.
var authorModel = mongoose.model('authorModel', authorSchema);
Lastly query your model and get the value you need
authorModel.find(
{
name: 'Rohit'
},
function (err, result) {
console.log(result)
});
I put my schema and controller on separate files. How you organise your code structure is up to you.
I pretty much followed this blog when I first learnt to build APIs on NodeJS. You might find this useful as well!

Push new object to nested mongodb document where particular condition matches within a sub document

I am new to Nodejs and Mongodb. I am building Message Chat Functionality in my project. I have done with Message Schema.
This is my User Model Schema:
var UserSchema = new mongoose.Schema({
name : {
type : String
},
email : {
type : String
},
password : {
type : String
},
chats : [{
chatId : String,
messages : [{
type : mongoose.Schema.Types.ObjectId,
ref : 'Message'
}]
}]
});
I want to add all the new message objects to the subdocument where chatId is matched. So,that I can easily use it on front end (which is Angular) with structured
I have tried this:
var msg = new Message({
senderId : req.user._id,
to : toUser,
from : user,
message : req.body.msg,
datetime : new Date()
})
msg.save();
const chatFr = await User.findOneAndUpdate(
{ 'chats.chatId' : req.user._id },
{ $push : { 'chats' : msg }}
)
It is creating a separate object.I don't know how to use 'where' in sub-documents here. I am coming from Sql background. Please help how to execute conditional queries in sub documents in mongodb/mongoose
Try this:
await User.findOneAndUpdate(
{ 'chats.chatId' : req.user._id },
{ $addToSet: { 'chats.$.messages' : msg }}}
)
You need to insert using the $ position operator. You can also utilize $addToSet.

Inserting array in mongodb in nodejs

i have two variable name and place
var name = 'ram';
var place = ['agra','delhi'];
my Schema is like
var Person= new Schema({
about :
{
name: {type : String},
place: {type : String}
}
,
});
I used query
var person = new Person({
about :
{
name : name,
place : place
}
});
person.save(function(){});
but the problem is that place store as a string in database
name : 'ram',
place : 'agra,delhi'
,so when i applying a query for searching place='agra' ,it gives null output.
But when i search place='agra,delhi' it produces result.
I want that this place store as array in database like
name : 'ram',
place : ['agra','delhi']
Please help me in this.
Change your schema to store places as array
var Person= new Schema({
about : [
{
name: {type : String},
places: [{type : String}]
}
],
});

Save multiples Objects At Once Mongo(Many To Many Mongoose)

this is my scene:
I have 2 collections(tables):Projects and students(the relation is many to many).
My models are:
Project:
var ProjectSchema = new Schema({
name: {
type: String
},
description: {
type: String
},
user : {
type : Mongoose.Schema.Types.ObjectId,
ref : "User"
}
});
Mongoose.model('Project', ProjectSchema);
User:
var Userchema = new Schema({
name: {
type: String
},
surname: {
type: String
},
project : {
type : Mongoose.Schema.Types.ObjectId,
ref : "Project"
}
});
Mongoose.model('User', UserSchema);
In my view I have 2 inputs where receive name and description of project, then have multiselect where choose 1 or multiples users for this project. When I Click OK should:
Create project, and add to user all users selected as objects in BBDD.
Update user, with project asociation.
I try the next, but only funcion if I choose 1 user:
exports.addUserProject = function(req, res) {
var project=new svmp.Project();
project.name=req.body.name;
project.description=req.body.description;
project.user=req.body.user[0]._id;
project.save(function(err,project){
if (err) {
return res.send(400, {
message : getErrorMessage(err)
});
} else {
res.jsonp(project);
}
})
};
The result in my BBDD is the next:
{ "_id" : ObjectId("57a200a38fae140913ac5413"), "user" : ObjectId("578f41ddb0641d961416c3f5"), "name" : "Project1", "Description" : "Project1 Desc","__v" : 0 }
Thanks for your help
First in your schema definition, since the relationship is many-to-many, you should change the ref to an array of the referenced objects. For example change the user property of projectSchema to an array of object ids like so,
var ProjectSchema = new Schema({
name: {
type: String
},
description: {
type: String
},
user : [{
type : Mongoose.Schema.Types.ObjectId,
ref : "User"
}]
});
Do the same for the project property of the userSchema.
Secondly, on this line project.user=req.body.user[0]._id; you are setting the the _id of only the first selected user as the user while ignoring every other selected users. This is why your code only works for one user. Instead, I will suggest you use a simple loop to push all selected users' _id to the project's user property. You can use a forEach loop as given below.
var selectedUsers = req.body.user;
selectedUsers.forEach(function(u){
project.user.push(u._id)
})
You can also do this with a simple for loop if you wish.
I believe the suggestions above should fix the issues you described.

MongoDB default values are not saved, instead re-calculated at runtime

I'm building a simple REST app on the Yeoman Express MVC generator with MongoDB.
This is my MongoDB/Mongoose model (updated with complete update.js model):
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var UpdateSchema = new Schema({
title: String,
text: String,
authors: String,
url: String,
imageUrl: String,
dateCreated: { type: Date, default: Date.now },
reloadNeeded: { type: Boolean, default: true }
});
mongoose.model('Update', UpdateSchema);
This is what the data looks like in the Mongo client:
> db.updates.find();
{ "_id" : ObjectId("5476453f8920d05ecdef4eec"), "title" : "Hello World", "text" : "yoda yoda" }
{ "_id" : ObjectId("547653748920d05ecdef4eed"), "title" : "Hihi", "text" : "mookie" }
And this is the JSON output from my Express app:
[
{"_id":"5476453f8920d05ecdef4eec","title":"Hello World","text":"yoda yoda","reloadNeeded":true,"dateCreated":"2014-11-27T10:50:10.078Z"},
{"_id":"547653748920d05ecdef4eed","title":"Hihi","text":"mookie","reloadNeeded":true,"dateCreated":"2014-11-27T10:50:10.078Z"}
]
So, dateCreated and reloadNeeded are set at runtime - but I'd rather want them set (and persisted) when I create the documents. What's going on?
Update: seems like values are persisted if I create from Mongoose rather than the MongoDB shell.
Do you use mongoose for data model? If it so, default values will be created on document construction http://mongoosejs.com/docs/2.7.x/docs/defaults.html
Anyway I assume the reason is in defaults

Resources