How can i make schema using mongoose for given output? - node.js

i want to store data like this but i have made schema but i don't think i have made right way please some one suggest me to get this done
{
"_id": {
"$oid": "5705f793e4b0acd6e2456804a"
},
"Categories": [
{
"mainmodels": [
{
"submodels": [
{
"price": "2000",
"submodelname": "lumia021",
"Remainingphones": "0",
"Bookedphones": "0",
"Numofphones": "10"
},
{
"price": "3000",
"submodelname": "lumia21",
"Remainingphones": "0",
"Bookedphones": "0",
"Numofphones": "20"
}
],
"Status": "Active",
"modelname": "lumia",
"fromdate": "2016-04-01T16:39:12.051Z",
"todate": "2016-04-31T19:19:44.051Z"
}
],
"brand": "nokia"
}
],
"rank": "1",
"name": "kalasipalaya"
}
schema design :
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var submodelSchema = {
submodelname: {type:String, required: false},
price: {type:String, required: false},
Remainingphones: {type:String, required: false},
Bookedphones: {type:String, required: false},
Numofphones: {type:String, required: false}
};
submodelSchema = 'new Schema('+ submodelSchema +',{_id:true})';
var typeSchema = {
brand: {type:String, required: false},
mainmodels: {
Status: {type:String, required: false},
modelname: {type:String, required: false},
fromdate: {type:String, required: false},
todate: {type:String, required: false}
},
subservices: [submodelSchema], default:[]
};
typeSchema = 'new Schema('+typeSchema +',{_id:true})';
var PhoneSchema = new Schema({
rank: {
type: String,
default: '',
trim: true
},
name: {
type: String,
default: '',
trim: true
},
Categories: [typeSchema], default:[]
});
mongoose.model('Phone', PhoneSchema);
i have added my schema design .is that design right? some one help me out bcoz when i update particular field it's not updating

Related

Mongoose: Populate an array of related values

I'm fairly new to Mongo and Mongoose, so if this question is rather silly then feel free to point me in the right direction.
I have a API with models for users and stories that they published. When I display the users, I want the stories to show as well.
The relation is drawn rather simply:
const userSchema = mongoose.Schema({
username: {
type: String,
unique: true,
},
password: String,
firstName: {
type: String,
required: false,
},
lastName: {
type: String,
required: false,
},
birthday: {
type: Date,
},
bio: {
type: String,
required: false,
},
country: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Country',
},
stories: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Story',
}]
})
With a stories scheme declared as such:
const storySchema = new mongoose.Schema({
name: {
type: String,
max: 255,
},
url: {
type: String,
unique: true,
},
description: {
type: String,
required: false,
},
length: {
type: Number,
default: 0,
},
createdAt: Date,
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
language: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Country'
},
type: {
type: mongoose.Schema.Types.ObjectId,
ref: 'StoryType'
},
genre: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Genre'
},
})
I print the values using the simple find method (the action for now is only meant to show all of them.
app.get('/list-users', async (req, res) => {
const users = await User.find().populate('country').populate('stories').exec();
res.json(users);
});
Unfortunately, although the results show all the values properly, the stories array does not get populated at all.
[
{
"_id": "6127ce5b0576979256fd3e08",
"username": "test",
"password": "123",
"firstName": "tst",
"lastName": "tst",
"birthday": "1995-11-02T00:00:00.000Z",
"country": {
"_id": "6127c020f95eb5abf72f713a",
"name": "Poland",
"languange": "Polish",
"__v": 0
},
"stories": [],
"__v": 0
}
]
The docs have a clear indicator that such schemas will return an empty array, and I am aware I could just run a find by User and populate with that but I'm wondering what is the cleanest solution to apply in a situation like this.
Any help would be of great value.

mongoose multiple field select not working

With below schema i am trying to find with selected fields. In result I receive only first 2 org_name and description, but others not receiving. any idea. I am new to mongoose. I am not able to find any reason from documentation too. Any help will be appreciated.
My schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let JobsSchema = new Schema ({
_id: {type:String, required: true, max:100},
sector: {type:String, required: true, max:100},
category: {type:String, required: true, max:100},
apply_mode: {type:String, required: true, max:100},
org_name: {type:String, required: true, max:100},
description: {type:String, required: true},
start_date: {type: Date},
end_date: {type: Date},
total_openings: {type: Number},
total_openings_description: {type:String},
min_salary: {type: Number},
max_salary: {type: Number},
salary_description: {type: String},
apply_steps: {type: String},
tags: [],
additional_dates: [{
additional_date_label: {type:String, required: true, max:100},
additional_date_value: {type:Date},
}],
age_limits: [{
age_limit_label: {type:String, required: true, max:100},
age_limit_min_value: {type: Number},
age_limit_max_value: {type: Number},
}],
application_fees: [{
application_fee_label: {type:String, required: true, max:100},
application_fee_value: {type: Number},
}],
url_links: [{
url_link_label: {type:String, required: true, max:100},
url_link_value: {type:String, required: true, max:100},
}]
},
{ collection: 'Jobs' }); // this line to match name in db
module.exports = mongoose.model('jobs', JobsSchema);
My query:
Job.find(
{},
"org_name description start_date end_date total_openings min_salary max_salary",
{ sort: { start_date: "asc" }, skip: pageNumber * pageSize, limit: pageSize },
(err, jobs) => {
if (err) {
res.render("error", {
errMsg: "issue in getting records. Try after sometime.",
errBody: err
});
}
if (jobs) {
res.render("listJob", {
jobs: jobs
});
}
}
);
Result
[
{
"_id": "Job1",
"org_name": "Test org",
"description": "<p>Test Desc</p><p><b>Hello world</b></p>"
},
{
"_id": "Job2",
"org_name": "Test org11",
"description": "<p>Test descr</p>"
},
{
"_id": "Job10",
"org_name": "Test inc 1",
"description": "<p>,smdfndfskj</p>"
}
]
I finally found that projection fields should be there in all documents then only it will apply.

How to select all the experiences from a specific user profile in Node and Mongoose from embedded schema

I'm building an API in NodeJS Express and MongoDB using Mongoose.
I created a Profile model that embeds the Experience schema.
Like:
{
"_id": "5e26ff6d5be84a3aeeb2f7bb",
"username": "some"
<fields of the profile>
"experience": [
{
"image": "",
"createdAt": "2020-01-21T13:41:01.873Z",
"updatedAt": "2020-01-21T13:41:01.873Z",
"_id": "5e26ff6d5be84a3aeeb2f7bc",
"title": "Senior Dev",
"role": "Dev",
"company": "ArosaDev",
"startDate": "2018-12-03T23:00:00.000Z",
"endDate": null,
"description": "",
"area": ""
}
],
"createdAt": "2020-01-21T13:41:01.874Z",
"updatedAt": "2020-01-21T13:41:01.874Z",
"__v": 0
}
The problem is I have to create an endpoint GET which gets for one profile all the experiences.
experienceRouter.get("/:username", async(req, res) => {
console.log(req.params.username);
const experiences = await Profiles.findOne({"username":req.params.username} ??? );
res.send(experiences);
});
I know I should select the embedded field experience and get back all the experiences but I don't know how should I do with Mongoose in my route.
I don't know what comes next after I select the username and how I can select the all experience for the username I'm requested.
I'm new to this and cannot find any good references explaining to me that for good.
I will appreciate an example of how a route like this should be done.
My model:
// Profile Schema model
// Embedded we have the Experience as []
const mongoose = require("mongoose");
const { isEmail } = require("validator");
const experienceSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
role: {
type: String,
required: true
},
company: {
type: String,
required: true
},
startDate: {
type: Date,
required: true
},
endDate: {
type: Date
},
description: {
type: String
},
area: {
type: String
},
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
},
image: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
}
})
const profileSchema = new mongoose.Schema({
firstname: {
type: String,
required: true
},
surname: {
type: String,
required: true
},
email: {
type: String,
trim: true,
lowercase: true,
unique: true,
required: true,
validate: {
validator: string => isEmail(string),
message: "Provided email is invalid"
}
},
bio: {
type: String,
required: true
},
title: {
type: String,
required: true
},
area: {
type: String,
required: true
},
imageUrl: {
type: String,
required: false,
default: "https://via.placeholder.com/150"
},
username: {
type: String,
required: true,
unique: true
},
experience: [
experienceSchema
],
createdAt: {
type: Date,
default: Date.now,
required: false
},
updatedAt: {
type: Date,
default: Date.now,
required: false
}
});
const collectionName = "profiles";
const Profile = mongoose.model(collectionName, profileSchema);
module.exports = Profile;
replace your code with below
You can mention your fields which you need in the second argument of function this is called projection as mentioned
So for including of fields use 1 and for excluding fields use 0
experienceRouter.get("/:username", async(req, res) => {
console.log(req.params.username);
const profile = await Profiles.findOne({"username":req.params.username},{experience:1 ,username:1, _id:0}).lean();
res.send(profile);
});

Issue with virtual population in Mongoose

I am using mongo DB with node.js and all models is in common folder and using virtual population to communicate between the models.For Example model1->model2->model3(model1 have the dependencies of model2 and model2 have the dependencies of model3).
Here is the code:
var packageGroupSchema = new Schema(
{
packageGroupCode: { type: String, required: true, unique: true},
packageGroupName: { type: String, required: true },
description: String,
**moduleId: { type: Schema.Types.ObjectId, required: true },**
active: Boolean,
createdDate: { type: Date, default: Date.now},
lastUpdatedDate: { type: Date, default: Date.now}
},
{
toJSON: { virtuals: true }
}
);
packageGroupSchema.virtual('moduleData', {
ref: 'Module',
localField: 'moduleId',
foreignField: '_id',
justOne: true
});
2nd Model:
//module Schema
var moduleSchema = new Schema(
{
moduleCode: { type: String, required: true, unique: true},
moduleName: { type: String, required: true },
description: String,
**categoryId: { type: Schema.Types.ObjectId, required: true },**
active: Boolean,
createdDate: { type: Date, default: Date.now},
lastUpdatedDate: { type: Date, default: Date.now}
},
{
toJSON: { virtuals: true },
toObject: {virtuals: true}
}
);
moduleSchema.virtual('categoryData', {
ref: 'Category',
localField: 'categoryId',
foreignField: '_id',
justOne: true
});
If I am runing the api for first model so I am geeting the data of dependencris(category) form the 2nd model.
Here is the result I am getting:
{
"_id": "59410a5dab85113a7cdc0507",
"packageGroupCode": "P02",
"packageGroupName": "package2",
"description": "package2",
"moduleId": "5940efeadb8fe72a8cb4e056",
"active": true,
"__v": 0,
"lastUpdatedDate": "2017-06-14T11:30:43.798Z",
"createdDate": "2017-06-14T11:30:43.798Z",
"moduleData": {
"_id": "5940efeadb8fe72a8cb4e056",
"moduleName": "module name",
**"categoryData": null,**
**"id": "5940efeadb8fe72a8cb4e056"**
},
**"id": "59410a5dab85113a7cdc0507"**
}
Can anybody tell me what I have to do to ignore catergoryData in moduleDate and id repetition.
Expexted JSON should be like this:
{
"_id": "59410a5dab85113a7cdc0507",
"packageGroupCode": "P02",
"packageGroupName": "package2",
"description": "package2",
"moduleId": "5940efeadb8fe72a8cb4e056",
"active": true,
"__v": 0,
"lastUpdatedDate": "2017-06-14T11:30:43.798Z",
"createdDate": "2017-06-14T11:30:43.798Z",
"moduleData": {
"_id": "5940efeadb8fe72a8cb4e056",
"moduleName": "module name"
}
}
if your result is stored in "theObject" you can remove the keys like this:
delete theObject["id"];
delete theObject["moduleData"]["id"];
delete theObject["moduleData"]["categoryData"];

Mongoose returns null array when populate

I'm trying to create a webapp with mongoose and nodejs. This is the first time i'm using mongoose and nodejs so i'm not quit good at it.
I have a person model:
var PERSON = new mongoose.Schema({
name: {type: String, required: true},
zipcode: {type: String, required: true},
city: {type: String, required: true},
street: {type: String, required: true},
address: {type: Number, required: true},
email: {type: String, required: true},
type: {type: String, enum: ['lid', 'passant'], required: true},
ships: {
type: [{
name: {type: String, required: true},
length: {type: Number, required: true},
type: {type: String, required: true},
picture: {type: Buffer, required: false}
}],
required: false
},
user: {
type: {
userName: {type: String, required: true},
password: {type: String, required: true},
passwordKey: {type: String, required: true},
roles: {type: [{type: mongoose.Schema.Types.ObjectId, ref: 'role'}], required: true}
},
required: false
}
},
{
collection: 'PERSON'
});
And the rol model:
var ROLE = new mongoose.Schema({
name: {type: String, required: true}
},
{
collection: 'ROLE'
});
When i'm trying to run a find query on the person model, I want to populate the user.roles array. But as a result it remains empty.
/ GET a specific person by id or type/
server.get('/api/person/:id', function (req, res, next) {
if (helper.isValidObjectID(req.params.id)) {
person.findById(req.params.id).populate("user.roles").exec(function (err, result) {
if (err) {
res.status(404).json(err);
} else {
res.status(200).json(result);
}
}
);
} else {
next();
}
}, function (req, res, next) {
person.find({type: req.params.id}).populate('user.roles').exec(function (err, result) {
if (err) {
res.status(404).json(err);
} else {
res.status(200).json(result);
}
});
});
and as a result i get:
{
"_id":"553f79d4f1481c0c14b42d59",
"name":"Wilco Boogert",
"zipcode":"4305RH",
"city":"Ouwerkerk",
"street":"baalpapenweg",
"address":2,
"email":"wilcoboogert17#gmail.com",
"type":"lid",
"user":{
"userName":"wboogert",
"password":"sha1$168fd599$1$502b965cb083ebdfcafb17e655455ef63779e1a1",
"passwordkey":"kfjvlksdfm",
"roles":[
]
},
"__v":0,
"ships":[
{
"name":"titanic",
"length":269,
"type":"Olympic-klasse",
"_id":"553f79d4f1481c0c14b42d5a"
}
]
}
The orginal object in the database is:
{
"_id": {
"$oid": "553f79d4f1481c0c14b42d59"
},
"name": "Wilco Boogert",
"zipcode": "4305RH",
"city": "Ouwerkerk",
"street": "baalpapenweg",
"address": 2,
"email": "wilcoboogert17#gmail.com",
"type": "lid",
"user": {
"roles": [
{
"$oid": "5522996f0fff331ed03cae6c"
}
],
"passwordkey": "kfjvlksdfm",
"password": "sha1$168fd599$1$502b965cb083ebdfcafb17e655455ef63779e1a1",
"userName": "wboogert"
},
"ships": [
{
"name": "titanic",
"length": 269,
"type": "Olympic-klasse",
"picture": "<Binary Data>",
"_id": {
"$oid": "553f79d4f1481c0c14b42d5a"
}
}
],
"__v": 0
}
so as you an see the roles is empty. And I search the web but i cannot find what the problem is. Can annyone help me?
You should replace this line :
roles: {type: [{type: mongoose.Schema.Types.ObjectId, ref: 'role'}], required: true}
with this one :
roles: {type: [{type: mongoose.Schema.Types.ObjectId, ref: 'ROLE'}], required: true}
In fact, the reference must be the exact same name as it's defined :
collection: 'ROLE'
It's case sensitive.

Resources