Mongoose Schema in node js - node.js

Mongo Database
I want to create the data model(Schema) in node js according to the the database shown in the picture. How to create the data model of array in node js and also the inside the array which have object, which also contain another array?

const mongoose = require('mongoose');
mongoose.pluralize(null);
const Schema = mongoose.Schema;
const indicatorsSchema = new Schema({
name:String,
metrics:[String] //[String] define array of string
}, { _id: false });
const Learning = new Schema({
learningEvents: String,
learningActivities: [String], //[String] define array of string
indicators:[indicatorsSchema] // define object as above
}, { versionKey: false })

Related

How do I update the existing documents' schema?

I'm using mongoose to do some MongoDB operations.
At the beginning the category was number,
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const sampleSchema = new Schema({
category: {
type: Number,
}
})
module.exports = mongoose.model("SampleSchema", sampleSchema);
Now the category changed to String, So I changed the model like this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const sampleSchema = new Schema({
category: {
type: String,
}
})
module.exports = mongoose.model("SampleSchema", sampleSchema);
The problem is, I have already inserted 200 records into this collection. Is there any way to update the category value with a string and change its type to string?
Please get All data by query and update it one by one in loop.
Like:
db.tableName.find( { 'status' : { $type : 1 } } ).forEach( function (val) {
val.status = new String(val.status);
db.tableName.save(val);
});
I changed the category to mixed, that's working fine with numbers and string.
Thanks for the help #prasad_

How can i insert data to a schema array in nodejs?

I have a schema as shown below and I was trying to insert a value to that schema but data is not being assigned. How we can assign data to a schema array in nodejs?
building is my schema instance.
my schema is shown below
geoValues: [
{
latitude: Number,
longitude: Number,
}
],
I tried like below for assigning data to my schema
building. geoValues.latitude = latitude;
building. geoValues.longitude = longitude;
Check whether your mongoose schema looks like this,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const buildingSchema = new Schema({
geoValues: [{
latitude: Number,
longitude: Number
}]
});

How to implement more than one collection in get() function?

My model university.js
const mongoose = require('mongoose');
const UniversitySchema = mongoose.Schema({
worldranking:String,
countryranking:String,
universityname:String,
bachelorprogram:String,
masterprogram:String,
phdprogram:String,
country:String
},{collection:'us'});
const University =module.exports = mongoose.model('University',UniversitySchema);
My route.js
const express = require('express');
const router = express.Router();
const University = require('../models/university');
//retrieving data
//router.get('/universities',(req,res,next)=>{
// University.find(function(err,universities){
// if(err)
// {
// res.json(err);
//}
// res.json(universities);
//});
//});
router.get('/usa',function(req,res,next){
University.find()
.then(function(doc){
res.json({universities:doc});
});
});
module.exports= router;
How to implement multiple collections in this get() function? I put my collection name in the model. Please help me with a solution to call multiple collections in get() function.
Here is Example to use multiple collection names for one schema:
const coordinateSchema = new Schema({
lat: String,
longt: String,
name: String
}, {collection: 'WeatherCollection'});
const windSchema = new Schema({
windGust: String,
windDirection: String,
windSpeed: String
}, {collection: 'WeatherCollection'});
//Then define discriminator field for schemas:
const baseOptions = {
discriminatorKey: '__type',
collection: 'WeatherCollection'
};
//Define base model, then define other model objects based on this model:
const Base = mongoose.model('Base', new Schema({}, baseOptions));
const CoordinateModel = Base.discriminator('CoordinateModel', coordinateSchema);
const WindModel = Base.discriminator('WindModel', windSchema);
//Query normally and you get result of specific schema you are querying:
mongoose.model('CoordinateModel').find({}).then((a)=>console.log(a));
In Short,
In mongoose you can do something like this:
var users = mongoose.model('User', loginUserSchema, 'users');
var registerUser = mongoose.model('Registered', registerUserSchema, 'users');
This two schemas will save on the 'users' collection.
For more information you can refer to the documentation: http://mongoosejs.com/docs/api.html#index_Mongoose-model or you can see the following gist it might help.
Hope this may help you. You need to modify according to your requirements.

How to define a nested schema in mongoose?

My mongo record is like this:
{
"_id":{"$oid":"5550b6de437f572112a29f1a"},
"cv_count":177732,
"gender_info": {"male_count": 50, "female_count": 32}
"stability_info_list":[{"ratio":8.802558610369414e-05,"total_count":34081,"years":0},{"ratio":5.868372406912943e-05,"total_count":34081,"years":1}],
"zhineng_id":"IT Manager"
}
I write the schema like this:
var ZhinengGenderSchema = new Schema({
male_count: Number,
female_count: Number
});
var ZhinengStabilitySchema = new Schema({
ratio: Number,
total_count: Number,
years: Number
});
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: ZhinengGenderSchema,
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
But I got this excetion:
TypeError: Undefined type `undefined` at `gender_info`
Did you try nesting Schemas? You can only nest using refs or arrays.
so mongoose doesn't support nest schemas? But my database has already been there, I cannot change, so how can I define my schema?
Just don't create a new schema for the subdocuments and you should be fine, i.e.:
var ZhinengGenderSchema = {
male_count: Number,
female_count: Number
};
var ZhinengStabilitySchema = {
ratio: Number,
total_count: Number
years: Number
};
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: ZhinengGenderSchema,
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
With mongoose you can define nesting (embedded) schemas in Array, like this:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var bookSchema = new Schema({
value: { type: String }
});
var authorSchema = new Schema({
books: [bookSchema]
});
Or by reference
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = mongoose.Schema.Types.ObjectId;
var auhtorSchema = new Schema({
book: { type: ObjectId, ref: 'Book'}
});
You may choose what is more appropriate for you
As far as I know, this is due to a current limitation of Mongoose. You cannot
declare a schema field to include a single sub-document: you have to use an array, instead. See this: https://github.com/Automattic/mongoose/pull/585
You can set up later the proper business logic in order to ensure that only one sub-element will be added.
Try this:
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: [ZhinengGenderSchema],
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
This way, each sub-document has got its own _id in MongoDB (even though it does not lie in a specific collection). See more: http://mongoosejs.com/docs/subdocs.html
You could also prefer something like this:
var ZhinengStats = new Schema({
cv_count: Number,
gender_info: [{male_count: Number, female_count: Number}],
stability_info_list: [ZhinengStabilitySchema],
zhineng_id: String
})
In this case, you nest a schema inside another. The single gender_info element does not have the dignity of a document.

Accessing subdocument properties in mongoose

I am using a MEAN stack to build this application.
Here is my subject.js schema:
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var topics = require('./topic');
var subjectSchema = new schema({
_category : {
type: String,
default: ""
},
topics: [topics.schema]
});
module.exports = mongoose.model('Subject', subjectSchema);
and my topics.js schema:
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var otherstuff = require('./otherstuff');
var otherstuff2 = require('./otherstuff2');
var topicSchema = new schema ({
title: String,
otherstuff: [mongoose.model('otherstuff').schema],
otherstuff2: [mongoose.model('otherstuff2').schema]
});
module.exports = mongoose.model('Topic', topicSchema);
What I am having difficulty with is how to access my topicSchema to populate it with forms from my front end.
I can save information to the subjectSchema, but not the sub documents.
I have tried using this as outlined in another article:
var Subject = mongoose.model('Subject', subjectSchema);
Subject.find({}).populate('subjects[0].topics[0].title').exec(function(err, subjects) {
console.log(subjects[0].topics[0].title);
});
But I continue to get TypeError: Cannot read property 'title' of undefined. How do I access the title property?
populate in mongoose is used to populate referenced documents, that are marked with ref attribute (see more info in the docs). Sub-documents on the other hand are available when do a simple query because they are actually an array of custom objects, so if you remove the populate method your query will work as expected:
Subject.find({}).exec(function(err, subjects) {
console.log(subjects[0].topics[0].title);
});

Resources