How to connect schemas with each other in mongooseJS? - node.js

Basically what I am trying to achieve is the following:
In my iOS application a QR-Code can be scanned to get the ID of a specific lounge and with that its JSON data (only ID and name for now) saved in MongoDB.
Every lounge is able (but doesn't have to) to add products to their lounge, so that in the end, after scanning the QR-Code, a customer is able to see which products are offered.
A product contains only a name and imageURL for now, but not a price, because the price can variate and be set by owners of a lounge. So a price of one and the same product can be different.
I would like to know, what the correct and best way is for implementing the schemas for that approach, so that I can easily fetch all products of a specific lounge, maybe based on its ID.
What I got so far:
lounge.js:
const mongoose = require('mongoose');
const loungeSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true }
});
module.exports = mongoose.model('Lounge', loungeSchema);
product.js
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
imageURL: { type: String, required: true, unique: true }
});
module.exports = mongoose.model('Product', productSchema);

Basically you can use mongoose populate. You can achieve this by storing the products in separate collection and basically populate an array on the lounge schema using the _id for the lounge let me show you an example:
Your lounge schema would be something like this
const mongoose = require('mongoose');
const loungeSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true }
products: [type: Schema.Types.ObjectId, ref: 'Products' ]
});
module.exports = mongoose.model('Lounge', loungeSchema);
And your product schema
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
imageURL: { type: String, required: true, unique: true }
});
module.exports = mongoose.model('Product', productSchema);
When saving creating a lounge just add the _id of the product to products array that apart of the lounge schema.
So basically you find the product and retrieve its _id.
To run a find query it would be something like this:
lounge.find({}).populate('products').exec();
products array will then have the related products for each lounge

Related

Is this the best way to design a mongodb schema?

I'm fairly new to programming, and am now at the stage where I am working on projects before starting to apply for jobs. I’m working on an express project and wanted some advice on my schema design, just in case I’m going about things in a horrible way.
The premise of the project is a desk booking app. A business administrator can create an account to register a company and add multiple offices if needed. Employees can also register as employees of a company using the unique company code and passcode, and then book desks in different offices.
This is the schema I have designed, I’ve modelled the data in this way as I want to be able to access the data in different ways e.g. an employee viewing all bookings they have made, as well as an employer viewing all bookings made in an office.
Any feedback would be much appreciated! Thanks in advance.
NB: When building the project I will have each schema in a different file, and I know I haven't required all the dependencies I will need. The purpose of this question is purely on best practices for mongoose schema design.
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const CompanySchema = new Schema({
companyName: String,
companyLogo: String,
uniqueCompanyCode: String,
companyPasscode: String,
companyAdmin: [
{
type: Schema.Types.ObjectId,
ref: "User"
}
],
offices: [
{
type: Schema.Types.ObjectId,
ref: 'Office'
}
],
})
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
bookings: [
{
type: Schema.Types.ObjectId,
ref: 'Booking'
}
]
})
UserSchema.plugin(passportLocalMongoose);
const OfficeSchema = new Schema({
officeAddress:{
streetAddress: String,
town: String,
county: String,
postcode: String
},
floorPlan: String,
desks: [
{
deskNumber: Number,
bookings:{
type: Schema.Types.ObjectId,
ref: 'Booking'
}
}
]
})
const bookingSchema = new Schema({
bookedFrom: Date,
bookedTo: Date,
bookedBy: {
type: Schema.Types.ObjectId,
ref: "User"
}
})
If you’re using the architecture of Node.js, MongoDB with mongoose, you’ll create these schemas at the beginning of every project so it’s best to get familiar with them.
This is how we create a schema in mongoose.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
let productSchema = new Schema({
name: {
type:String,
required:true
},
price: {
type:Number,
required:true
},
isAvailable: {
type:Boolean
}
});
const productModel = mongoose.model("product", productSchema);
module.exports = productModel;
The first parameter of the mongoose.model is the name of the collection that will contain the documents. The second parameter is the schema. Now, we need is to export productModel so they can be used elsewhere.
const productModel = mongoose.model("product", productSchema);
This productModel is ready to be imported and used to create data following our schema in the product collection. This is a common development pattern when using Node.js and MongoDB. An ODM-like mongoose makes managing your data more intuitive.

Mongoose schemas cast error when adding a new category

I have two schemas, one collection and another category. A collection has many category and a category can have many collection items.
I'm looking to create a filter later on down the line.
category schema
const mongoose = require('mongoose')
let categorySchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true
},
collections: [{ type: mongoose.Types.ObjectId, ref: 'Collection' }]
})
module.exports = mongoose.model('category', categorySchema)
collection schema
const mongoose = require('mongoose')
let collectionSchema = new mongoose.Schema({
...
categories: [{
type: mongoose.Schema.Types.ObjectId, ref: 'categories',
required: true
}]
})
module.exports = mongoose.model('collection', collectionSchema)
truncated this to keep it relevant.
I'm not looking to populate the references yet as I'm only doing the backend for now, so I'm only rendering JSON for now.
I can create multiple category
and I can create a collection with a category as a collection must have at least one category
I can edit a collection and add a new category
However, sometimes I seem to get the following error
I'm not sure why maybe the database hasn't updated in the app, I am using nodemon so I'm not really sure what the issue could be here.
const CollectionSchema = new Schema({
name: String
categoryName: String
});
const CategorySchema = new Schema({
name: String
});
CollectionSchema.virtual('category', {
ref: 'Category', // The model to use
localField: 'name', // Find people where `localField`
foreignField: 'categoryName', // is equal to `foreignField`
// If `justOne` is true, 'members' will be a single doc as opposed to
// an array. `justOne` is false by default.
justOne: false,
options: { sort: { name: -1 }, limit: 5 } //you can add options as well
});
const Category = mongoose.model('Category', CategorySchema);
const Collection = mongoose.model('Collection', CollectionSchema);
Collection.find({}).populate('category').exec(function(error, categories) {
/* `categories.members` is now an array of instances of `Category` */
});
This link has additional Information

How to dynamically populate array of objects in mongoose?

I am trying to dynamically populate array of objects in mongoose. On my user model I want an array that contains all posts that user made. The problem is that I have multiple types of posts.
Different post models:
const ImagePost = mongoose.model('ImagePost', new Schema({ url: String }))
const TextPost = mongoose.model('TextPost', new Schema({ text: String }))
My user model looks like this:
const userSchema = new Schema({
userName: {
type: String,
required: true
},
posts: [{
postId: {
type: Schema.Types.ObjectId,
required: true,
refPath: "postModel"
},
postModel: {
type: String,
required: true,
enum: ['ImagePost', 'TextPost']
}
}]
})
const User = mongoose.model('User', userSchema)
How can I get the user from my database and automatically populate the posts the user made?
The whey I think it should work is this but for some reason it doesn't do anything:
User.findById('5d302c7caf1b8906ccb611b6').populate('posts.postId')
Changing your refPath from postModel to posts.postModel may solve your problem.

How to show relationship in mongoose?

I have two mongoose schemas 'user' and 'project' and i want to show relationship between these schemas like in mysql. How to do this?
And how can i pass user while creating a project?
User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Schema = mongoose.Schema();
const UserSchema = mongoose.Schema({
fullname: {type: String},
username : {type:String},
password: {type:String}
});
UserSchema.methods.encryptPassword = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(10), null);
};
UserSchema.methods.comparePassword = function(userPassword, cb) {
bcrypt.compare(userPassword, this.password, (err, isMatch) => {
if(err) throw err;
cb(null, isMatch);
});
}
module.exports = mongoose.model('User', UserSchema);
project.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema();
const User = require('./user');
const ProjectSchema = mongoose.Schema({
title: {type: String, required: true},
description: {type:String},
created_at: { type: Date, default: Date.now },
publish : { type: Boolean, default: false}
});
module.exports = mongoose.model('Project', ProjectSchema);
Creating schema in Mongoose isn't like creating schema in Relational DBMS, such as MySQL, PostGreSQL.
You can use objectId, bro.
If one project just can be handled by one user, you can use something like this.
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
But if one project is handled by multi users
users: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
Hope it will help
Schema Change
To create a relationship in Mongoose (MongoDB), create a property on your schema with the following properties
1. type: mongoose.Schema.Types.ObjectId
2. ref: "string name of the Collection this reference lives in"
For example, if you wanted a project to contain a reference to the users inside of it, you could do the fallowing
const mongoose = require('mongoose');
const Schema = mongoose.Schema();
const User = require('./user');
const ProjectSchema = mongoose.Schema({
title: {type: String, required: true},
description: {type:String},
created_at: { type: Date, default: Date.now },
publish : { type: Boolean, default: false},
users: [{type: Schema.Types.ObjectId, ref: 'User'}]
});
module.exports = mongoose.model('Project', ProjectSchema);
Example Opertaion
Given the above Schema, if you wanted to create a new Project and add users to it during creation, you would need to have those users' _id properties on hand (i.e. cached). That could mean making a prior query to the db to get all the users who will be a part of this project or having some client send you the user ids.
A much better option would be to create a project, and update its' users property as users are added or removed.
Here is a quick example
const Project = require('./models/Project.js');
let userIds = // get the user _ids some how
Project.create({
title: 'A sample',
description: 'The usual',
publish: true,
users: userIds
})
.then(callback);

How to structure many-to-many relationships in mongoose nodejs?

The scenario is as follows:
One product can be in Many orders, and one order can have many products. How to structure many-to-many relationships using mongoose and node.js ?
I have given the product model below. However, I am not sure how the order model should be. Can someone please help me figure this out. I am new to Node/ Mongoose and hope someone will help me out with this.
CODE
var mongoose = require('mongoose');
var productSchema = mongoose.Schema({
product:{
type: String,
unique: true,
required: true
},
price:{
type: String,
required: true
},
create_date:{
type: Date,
deault: Date.now
}
});
this is my product model
var mongoose = require('mongoose');
Schema = mongoose.Schema;
var productSchema = mongoose.Schema({
product:{
type: String,
unique: true,
required: true
},
price:{
type: String,
required: true
},
create_date:{
type: Date,
deault: Date.now
}
});
var Product = mongoose.model('Product', productSchema);
module.exports = product;
this order model
var mongoose = require('mongoose');
Schema = mongoose.Schema;
var orderSchema = mongoose.Schema({
orderNumber:{
type: Number,
required: true
},
products:[{type:Schema.Types.ObjectId, ref:'Product'}]
create_date:{
type: Date,
deault: Date.now
}
});
var Order = mongoose.model('Order', orderSchema);
module.exports = Order;
my result of json like this
product :
{
_id:1
product:"test",
price:100,
create_date:"20/11/91"
}
order :
{
orderNumber:123
product: [1] (ref of product id)
create_date:"20/11/91"
}

Resources