Referencing a specific attribute to another Schema in mongoose - node.js

May I know how to reference a specific field like in my code is the flowerName? I want to reference flowerName to the inventorySchema from stockSchema. Will this work?
const inventorySchema = ({
id: {type: mongoose.Schema.Types.ObjectId, ref: 'Stocks', required: true},
flowerName: {ref: 'Stocks', required: true},
orderName: {
type: String,
required: true
}
})
module.exports = mongoose.model('Inventory', inventorySchema);
const stockSchema = new Schema({
id: {
type: Number
},
flowerName: {
type: String,
required: true
}
module.exports = mongoose.model('Stocks', stockSchema);

You should reference inventory from stock
const inventorySchema = new Schema({
orderName: {
type: String,
required: true,
},
flowerName: {
type: String,
required: true,
},
});
module.exports = mongoose.model('Inventory', inventorySchema);
const stockSchema = new Schema({
id: {
type: Number
},
inventory: {
type: Schema.Types.ObjectId,
ref: 'Inventory',
required: true
}
});
module.exports = mongoose.model('Stocks', stockSchema);
You should then be able to reference flowerName by populating stock instances with:
const stock = Stocks.findOne({}).populate('inventory').exec();
if (stock) stock.inventory.flowerName

Related

How to receive an array from a model inside another model? (mongoose) (mongoDB)

I have an order model/schema, and my goal is that in this model in "list", I receive the information from the model cart in array format. How could I do this using ref?
cart model
const mongoose = require('mongoose');
const CartSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
note: {
type: String,
required: true,
},
price: {
type: Number,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Cart", CartSchema);
order
const mongoose = require('mongoose');
const OrderSchema = new mongoose.Schema(
{
list: {
name: String,
notes: String,
},
totalAmount: {
type: Number,
required: true,
},
payment: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
addressNote: {
type: String,
required: false,
},
createdAt: {
type: Date,
default: Date.now,
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Order", OrderSchema);
Basically receive in array format the information of the model cart in "list" in model order
You should define your list as an array of ObjectIds referring to the Cart model:
const OrderSchema = new mongoose.Schema(
{
list: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Cart'
}],
...
});
Then, to retrieve the values in list, just populate the Order:
Order.find({}).populate('list').exec();

Mongoose model how to have an array as property which contains same model as parent

So what I'm trying to do is I want to create a Note object inside note I have a subnote property, I want to have the subnote to be able to be as the same type as the parent model, Right now I'm achieving this by creating two same models with different names and both of them referencing each other for e.x this is the way I'm doing it:
Note schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const noteSchema = new Schema({
icon: {
type: String,
},
banner: {
type: String,
},
name: {
type: String,
required: true,
},
user_id: {
type: String,
required: true,
},
date: {
type: Date,
required: true,
default: Date.now,
},
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "sub_notes",
},
content: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "blocks",
},
],
});
module.exports = Note = mongoose.model("notes", noteSchema);
SubNote schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const subNoteSchema = new Schema({
icon: {
type: String,
},
banner: {
type: String,
},
name: {
type: String,
required: true,
},
user_id: {
type: String,
required: true,
},
date: {
type: Date,
required: true,
default: Date.now,
},
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "notes",
},
content: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "blocks",
},
],
});
module.exports = SubNote = mongoose.model("sub_notes", subNoteSchema);
But I'm not sure if the above method is the proper way to do it..., Please guide me. Thanks.
u can achieve this by simply doing this
const noteSchema = new Schema({
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "notes",
},
});
module.exports = Note = mongoose.model("notes", noteSchema);
or simply using "this" keyword
const noteSchema = new Schema({
sub_note: this
});
module.exports = Note = mongoose.model("notes", noteSchema);

Mongoose(mongoDB) Linking multiple schema's

Im relatively new to MongoDB and Mongoose. Im much used to MySQL so in used to inner joining tables on calls. Ive read a lot that you can link two Mongoose Schemas to achieve the same outcome. How would like like the two schemas together to when I make a call to get a chore by id it'll return the chore and then for the assignedTo & createdBy have the user scheme data for the said userId?
Chore Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ChoreSchema = new Schema({
title: {
type: String,
required: true
},
desc: {
type: String,
required: true
},
time: {
type: Number,
required: true
},
reaccurance: {
type: [{
type: String,
enum: ['Daily', 'Weekly', 'Bi-Weekly', 'Monthly']
}]
},
reward: {
type: Number,
required: true
},
retryDeduction: {
type: Number,
required: false
},
createdDate: {
type: Date,
default: Date.now
},
createdBy: {
type: String,
required: true
},
dueDate: {
type: Date,
required: true
},
status: {
type: [{
type: String,
enum: ['new', 'pending', 'rejected', 'completed', 'pastDue']
}],
default: ['new']
},
retryCount: {
type: Number,
default: 0,
required: false
},
rejectedReason: {
type: String,
required: false
},
familyId: {
type: String,
required: true
},
assignedTo: {
type: String,
required: false,
default: ""
}
});
let Chores = module.exports = mongoose.model('Chores', ChoreSchema);
module.exports.get = function (callback, limit) {
Chores.find(callback).limit(limit);
};
User Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
role: {
type: [{
type: String,
enum: ['Adult', 'Child']
}]
},
birthday: {
type: String,
required: false
},
familyId: {
type: String,
required: true
},
balance: {
type: Number,
required: true,
default: 0.00
}
});
let Users = module.exports = mongoose.model('Users', UserSchema);
module.exports.get = function (callback, limit) {
Users.find(callback).limit(limit);
};
Im trying to link ChoreSchema.createdBy & ChoreScheme.assignedTo by UserSchema._id
How I make the call in Node.js:
exports.index = function(req, res) {
Chore.get(function(err, chore) {
if (err)
res.send(err);
res.json({
message: 'Chore List',
data: chore
});
});
};
Mongoose has a more powerful alternative called populate(),
which lets you reference documents in other collections.
https://mongoosejs.com/docs/populate.html
Here is how you can link ChoreSchema.createdBy and ChoreScheme.assignedTo by UserSchema._id
var mongoose = require('mongoose');
const { Schema, Types } = mongoose;
var UserSchema = new Schema({
firstName: { type: String, required: true },
...
})
var ChoreSchema = new Schema({
title: { type: String, required: true },
...
//The ref option is what tells Mongoose which model to use during population
assignedTo: { type: Types.ObjectId, ref: 'Users' },
createdBy: { type: Types.ObjectId, ref: 'Users' },
})
let Chores = mongoose.model('Chores', ChoreSchema);
let Users = mongoose.model('Users', UserSchema);
Then in your express route handler you can populate assignedTo & createdBy like this
router.get('/chores/:id', function (req, res) {
const choreId = req.params.id;
Chores.find({ _id: choreId })
.populate('createdBy') // populate createdBy
.populate('assignedTo') // populate assignedTo
.exec(function (err, chore) {
if(err) {
return res.send(err)
}
res.json({ message: 'Chore List', data: chore });
});
})

Mongoose: Populate referenced SubDocument

I've the following schemas:
Occurence that references a competence in the CostCenter subdocuments competences.
const OccurrenceSchema = new mongoose.Schema({
date: {
type: Date,
default: Date.now,
},
competence: {
type: mongoose.Schema.Types.ObjectId,
ref: 'CostCenter.competences',
},
...
})
CostCenter where I've an array of subdocuments that can be ref by Occurence.
const CostCenterSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
competences: [CompetenceSchema],
});
And finally the Competence.
const CompetenceSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
});
When I try to populate the competence, I get "Schema hasn't been registered for model \"CostCenter.competences\".\nUse mongoose.model(name, schema)".
const occurrence_list = (request, response) => {
Occurrence.find()
.populate('occurrence origin tag entity method priority competence')
.then(occurrences => response.send(occurrences))
.catch(e => response.send(e));
};
How can I possibly populate the occurrence when referencing a subdocument?
First, you need to change your Occurrence model to this
const OccurrenceSchema = new mongoose.Schema({
date: { type: Date, default: Date.now },
competence: { type: mongoose.Schema.Types.ObjectId, ref:'CostCenter' }
});
mongoose.model('Occurrence', OccurrenceSchema);
and CostCenter model:
const CostCenterSchema = new mongoose.Schema({
name: { type: String, required: true, trim: true },
competences:[{ type: mongoose.Schema.Types.ObjectId, ref: 'Competence' }],
});
mongoose.model('CostCenter', CostCenterSchema);
finally Competence model:
const CompetenceSchema = new mongoose.Schema({
name: { type: String, required: true, trim: true }
});
mongoose.model('Competence', CompetenceSchema);
To populate the competence from Occurrence, you can do so:
Occurrence.find({ your_query })
.populate('competence')
.then(occurrences => response.send(occurrences))
.catch(e => response.send(e));
Hope it helps!

one to many relationship in mongoose

I'm using mean stack to create a hybrid app.I'm using nosql to create DB in mongoose.My DB consists of two tables one is 'donors' and another one is 'bloodGroup'.
My 'bloodGroup' schema is as follows:
module.exports = function(mongoose) {
var Schema = mongoose.Schema;
/* bloodGroup Schema */
var bloodGroupSchema = new Schema({
name: { type: String, required: true }
});
}
My 'Donor'schema is as follows:
/* Donor Schema */
var DonorSchema = new Schema({
Name: { type: String, required: true },
DOB: { type: Date, required: true, trim: true },
Sex: { type: String },
BloodGroupID: { type: Schema.Types.ObjectId, ref: 'BloodGroup', required: true },
ContactNo: { type: String, required: true },
LocationId: { type: Schema.Types.ObjectId, ref: 'Location', required:true },
EmailId: { type: String, required: true },
Password: { type: String, required: true }
});
When many donors refer to a single blood group then BloodGroup object Id error is reported.How to solve this problem?
You can refer this link for documentation: http://mongoosejs.com/docs/populate.html
Saving Refs
/* Donor Schema */
var DonorSchema = new Schema({
_id : {type: Number},
Name: { type: String, required: true },
DOB: { type: Date, required: true, trim: true },
Sex: { type: String },
BloodGroupID: { type: Schema.Types.ObjectId, ref: 'BloodGroup', required: true },
ContactNo: { type: String, required: true },
LocationId: { type: Schema.Types.ObjectId, ref: 'Location', required:true },
EmailId: { type: String, required: true },
Password: { type: String, required: true }
});
/* bloodGroup Schema */
var bloodGroupSchema = new Schema({
_bid :{ type: Number, ref: 'Donor' },
name: { type: String, required: true }
});
module.exports = mongoose.model('Donor', DonorSchema);
module.exports = mongoose.model('Blood', bloodGroupSchema);
var vidya = new Donor({ _id: 0, name: 'Vidya', sex: 'F' });
vidya.save(function (err) {
if (err) return handleError(err);
var blood = new BloodGroup({
name: 'B+',
_bid: vidya._id // assign the _id from the Donor
});
blood.save(function (err) {
if (err) return handleError(err);
// thats it!
});
});
Mongo is not a Relational database, relation one to many does not exist in mongDB. The question is quite confusing, but following the title, you should either embed the donnors into the BloodGroup, or create an Id field unique to which you will refer and do two queries.

Resources