I was googling for last two days but no success. I need to perform inner join in mongoose with two schema but not getting response my other collection.
My question is what am I missing in my code? Please help me with this.
I want to get result of class and subjects also.
exports.classSubjectList = async (req, res, next) => {
const obj = await ClassSubject.find().populate('classmodel').exec();
res.status(200).json({
success: true,
response: obj
});
};
//ClassSubjectModel
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
const classModel = require('../class/classModel');
const subjectModel = require('../subject/subjectModel');
var classsubject = new Schema({
ClassId: String,
SubjectId : String,
IsShow: { type: Boolean, default : true},
classmodel: { type: mongoose.Schema.Types.ObjectId, ref: classModel },
subjectmodel: { type: mongoose.Schema.Types.ObjectId, ref: subjectModel },
});
//Class Model
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
var classinfo = new Schema({
ClassName: String,
IsShow: { type: Boolean, default : true},
});
module.exports = mongoose.model('classinfo', classinfo);
//SUBJECT Model
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
var subject = new Schema({
SubjectName: String,
IsShow: Boolean,
});
module.exports = mongoose.model('subject', subject);
result
[
{
"IsShow": true,
"_id": "5e1efc0f354849246c472cfe",
"SubjectId": "5e1da60bf52acb30b87e92c4",
"ClassId": "5e1ec13ed777bf28d01e2481",
"__v": 0
}]
You should define ref as the name of your schema & not the object reference
Do it like this
classmodel: { type: mongoose.Schema.Types.ObjectId, ref: 'classinfo' }
subjectmodel: { type: mongoose.Schema.Types.ObjectId, ref: 'subject' },
// here 'classinfo' & 'subject' are the names you defined your schema with
You should populate both if you want a proper inner join
const obj = await ClassSubject.find().populate('classmodel').populate('subject').exec();
You must store ids of class & reference in classmodel & subjectmodel
key of your document for this to work
Hope this helps
Related
I am trying to get the matches array to contain the match and chatroom both of which are objectId with reference to different Schema. But when I log the match in a get operation I cannot understand what is logged in the matches section can someone help me with this.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const {ObjectId} = mongoose.Schema;
var match = new Schema({
match:{
type: ObjectId,
ref:'User'
},
chatroom:{
type:ObjectId,
ref:'Chatroom'
}
});
const matchList = new Schema({
user:{
type: ObjectId,
ref:'User'
},
likeSent:[
{
type: ObjectId,
ref:'User'
},{
timestamp:true
}
],
likeRecieve:[
{
type: ObjectId,
ref:'User'
},{
timestamp:true
}
],
matches:[match]
},{
timestamp:true
});
const MatchList = mongoose.model('Match',matchList);
module.exports = MatchList;
I am new to MongoDB references. Right now I have one collection which I call users. It stores all users and their keys. I have another collection which has data for each key.
I want to just use their key as the ID to connect them. So I will have each key generated and and the keyData will be empty when first created and then I will just keep adding objects to the keyData array. That is my plan, but I do not know how I create the relation with the schema.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//Create Schema
const userKey = new Schema({
_id : {
type : String,
required: true
},
key: {
type : String,
required: true
},
keyData: [key],
date: {
type: Date,
default: Date.now
}
});
module.exports = Key = mongoose.model('key', userKey);
This doesn't work because I cannot access the key before initialization. So how canI relate the two collections?
Schema #1: userData
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create User-data Schema
const userData = new Schema({
data: {
type: Array,
require: true
}
},
{
collection: 'data' // Mentioning collection name explicitly is good!
});
module.exports = mongoose.model('data', userData);
Schema #2: Keys
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create User-Key Schema
const userKey = new Schema({
key: {
type: String,
required: true
},
keyData: {
type: Schema.Types.ObjectId,
ref: 'data'
},
date: {
type: Date,
default: Date.now
}
},
{
collection: 'keys' // Mentioning collection name explicitly is good!
});
module.exports = mongoose.model('keys', userKey);
As per this link its not possible to set string as refs. So in your keys schema use ObjectId as ref.
Would something like this work?
const userData = new Schema({
_id : {
type : String,
required: true
},
data : {
type : Array,
require: true
}
});
const userKey = new Schema({
_id : {
type : String,
required: true
},
key: {
type : String,
required: true
},
keyData: [{ type: Schema.Types.ObjectId, ref: 'data' }],
date: {
type: Date,
default: Date.now
}
});
module.exports = KeyData = mongoose.model('data', userData);
module.exports = Key = mongoose.model('key', userKey);
Here's my product.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema; var ObjectId = mongoose.Schema.Types.ObjectId;
const ProductModel = new Schema(
{
name: {
type: String
},
//hidden code for better viewing
policyId: {
type: mongoose.Schema.Types.ObjectId
}
},
{
strict: false,
timestamps: true
}
);
const myDB = mongoose.connection.useDb('SampleDB');
module.exports = myDB.model('bf-product', ProductModel);
Here's my return-policy.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
const ReturnPolicyModel = new Schema(
{
name: {
type: String
},
description: {
type: String
},
addedById: {
type: String
},
status: {type: Number, default: 1}
},
{
strict: false,
timestamps: true
}
);
const myDB = mongoose.connection.useDb('SampleDB');
module.exports = myDB.model('bf-return-pol', ReturnPolicyModel);
Here's the query I'm running
const Product = require('../models/product.model');
let products = await Product.aggregate([
{
$lookup:
{
from: "bf-return-pol",
localField: "policyId",
foreignField: "_id",
as: "policies"
}
}
])
console.log(products)
When I run the query, policies always returns empty. I think the issue is because of the project using multiple databases, as I had a similar issue with paths with the populate keyword. So my question is this, how can I run the query as both the collections are in the same db?
product collection
return-policy collection
EDIT: The issue seemed to be that the collection was named as "bf-return-pols" and once I changed the from field in lookup, I could get the results.
I know that this question was asked many many times but i still can't find a solution
So this is my db
Product :
Ingredient :
Schemas :
ingredient.js
const mongoose = require("mongoose");
var IngredientSchema = new mongoose.Schema({
quantity: {
value: Number,
unit: String
},
comment: String,
product: { type: mongoose.Schema.Types.ObjectId, ref: "Product" }
});
module.exports = mongoose.model("IngredientSchema", IngredientSchema);
product.js
const mongoose = require("mongoose");
var ProductSchema = new mongoose.Schema({
name: {
type: String,
default: "",
trim: true,
required: "Name cannot be blank"
},
category: {
type: String,
default: "",
trim: true
},
convertion: [
{
unit_from: String,
unit_to: String,
value_from: Number,
value_to: Number
}
],
default_unit: String
});
const Product = (module.exports = mongoose.model(
"ProductSchema",
ProductSchema
));
this is the populate function :
ingredientRoutes.route("/:id").get(function(req, res) {
let id = req.params.id;
Ingredient.findById(id)
.populate("produit")
.exec()
.then(function(data) {
console.log(data.product, "***");
})
.catch(function(err) {
console.log(err);
});
});
this is the result that i'm getting :
just the id of the product without making the population
Any idea ?
I have a student collection when I want to report on a particular student with
studentId the report must be stored in report collection along with studentId
and what report I gave.I want to use individual collections
here is student schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var studentSchema = new Schema({
name: {
type: String,
required: true
},
dateofbirth: {
type: Date,
required: true
},
schoolname:
{
type:String,
required:true
},
standard:
{
type: Number,
required:true
}
}, {
timestamps: true
});
and here is report schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var reportSchema = new Schema({
date: {
type:Date,
required:true
},
comment:
{
type:String,
required:true
}
},
{
timestamps: true
});
var Report = mongoose.model('report', reportSchema);
module.exports = Report;
So how can I retrive studenId from student collection ?And how can I give report to a particular student?
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var studentSchema = new Schema({
name: {type: String, required: true},
dateofbirth: {type: Date, required: true},
schoolname: {type:String, required:true},
standard: {type: Number, required:true},
timestamps: true
});
var reportSchema = new Schema({
date: {type:Date,required:true},
comment: {type:String,required:true}
timestamps: true,
student_id: [{type: String, ref:'student',required: true}] //store your student{_id} relation here ref ==> is just a Collection name
});
mongoose.connect('mongodb://localhost/your_db_name_here', {
// using mongoose client to avoid promises exception
useMongoClient: true,
});
//just making your collection available to next controller.js file
module.exports= {
student : mongoose.model('student',studentSchema ),
report: mongoose.model('report', reportSchema)
};
controller.js I have been using express.js for your case
var db = require("./db.js");
var app = require("express")();
app.post("/api/student/register", (req, res) => {
var dbdata = {
name: req.body.name,
.......
}
db.student.create(dbdata, (er, callback) => {
if(er)return res.json("error");
return res.json("successfully inserted");
});
});
app.post("/api/student/report/create", (req, res) => {
//while creating a report you have to pass a Student primary key
var dbdata = {
date: req.body.data;
comment: req.body.comment,
student_id: req.body.student_id
// similar to foreign key relation ship}
}
db.report.create(dbdata, function(er, callback){
if(er)return res.json("err");
return res.json("successfully inserted");
});
});
your answer here
app.post("/particular/student/report", function(req, res){
db.report.find({student_id:"your student id here"}).populate('student_id').exec(function(err, data){
if(err)return res.json("db exception");
return res.json(data); //you will get all your student report for the particular student
});
});
here is
mongoose populate official docs
still if you have some other basic thing about mongoose or mean stack means kinldy refer to https://github.com/Muthukumars1994/Meanapp