First Schema:
const ProviderSchema = new mongoose.Schema({
provName : { type: String, index: true }
});
module.exports = mongoose.model('provider', ProviderSchema);
Second Schema:
const WebProviderSchema = new mongoose.Schema({
userId : { type: Schema.Types.ObjectId, ref: 'users'},
providerId : { type: Schema.Types.ObjectId, ref: 'providers'}
});
module.exports = mongoose.model('webProvider', WebProviderSchema);
How do I join these two schemas?
So far if I do the following, I only get data from the second schema:
webProvider
.find({userId : '23423df234434bc956'})
.populate("providers")
.exec( function (error, listData) {
console.log(listData);
});
To populate you should use local field providerId. Should be .populate("providerId") instead of .populate("providers").
webProvider.find({userId : '23423df234434bc956'})
.populate("providerId")
.exec( function (error, listData) {
console.log(listData);
});
To populate multiple field can use like :
.populate("providerId userId")
or
.populate("providerId")
.populate("userId")
Related
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);
I have two documents in mongodb:
export const Category = mongoose.model('Category', new mongoose.Schema({
name: { type: String },
}));
export const SubCategory = mongoose.model('SubCategory', new mongoose.Schema({
name: { type: String },
category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
}));
How to find All SubCategory that match Category by name?
I have try a lot of ways but I always getting null or error...
var name = '...';
SubCategory.find({ category: { name } });
SubCategory.find({ category: { name } }).populate('category');
You can use aggregation for the same. Please read this documentation https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
Note:- This answer is based on your collection and data you have entered. this is not perfect but this will help best to find the logic from this answer. :-)
//collection 1 schema
const collection1Schema = new Schema({
user_id: {
type: String,
required: true
},
status: {
type: String
}
});
mongoose.model('Collection1', collection1Schema);
//collection 2 schema
const collection2Schema = new Schema({
user_id: {
type: Schema.Types.ObjectId,
ref: 'user_id'
},
item: {
type: String
}
});
mongoose.model('Collection2', collection2Schema);
//find data from collection2
Collection2.find()
.populate('user_id')
.exec(function(err, foundDocuments) {
if (error) {
console.error(err);
} else {
console.log(foundDocuments);
}
});
For more info:- Mongoose populate
So I tried to migrate a new field to the mongoDB collections.
New field is a array that is filled with objects.
The migration runs and is successful, it even shows the new field when
looking the collections.
Problem comes when I try to add data to this field - it shows that the
field is undefined.
What should be done to overcome this problem?
Migration code:
exports.up = async function(db) {
await db
.collection('useractions')
.update({}, {
$set: {
history: []
}
}, {multi: true, upsert: false});
};
Code to populate the new field:
const bookId = req.body.bookId;
const timestamp = req.body.timestamp;
const userId = req.body.userId;
const container = {bookId, timestamp};
UserAction.update(
{ userId },
{$set: { history: container}},
(err, cb) => {
if(err)next({error: err});
res.status(200).json({
cb
})
})
EDIT:
Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userActionModel = new Schema({
userId: {
type: String
},
likes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Podcast',
default: []
}],
tags: {
type: [String],
default: []
},
orderedBook: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Show',
default: []
}]
})
module.exports = mongoose.model('userAction', userActionModel);
I succeed to make a deep population with find and the search key in first model, but now i want to find by key on the sub object generated by the deep populate.
I have three models : Product, Category, and Event
I want to find my Products by e_fk_club_id that is in Event model
I tried two solutions but they didn't work
First solution in find :
model.find({'categories.events.e_fk_club_id':id})`
Second solution with match :
`$match : { e_fk_club_id : id }`
these are my models
product.js
var ProductSchema = new mongoose.Schema({
p_id: Number,
p_name: String,
p_fk_category: {type: mongoose.Schema.Types.ObjectId, ref: 'categories'},
}
, {collection: 'products'});
module.exports = mongoose.model('products', ProductSchema);
Category.js
var CategorySchema = new mongoose.Schema({
c_id: Number,
c_name: String,
c_fk_event: {type: mongoose.Schema.Types.ObjectId, ref: 'events'},
}
, {collection: 'categories'});
module.exports = mongoose.model('categories', CategorySchema);
Event.js
var EventSchema = new mongoose.Schema({
e_id: Number,
e_name: String,
e_fk_club_id: Number,
}
, {collection: 'events'});
module.exports = mongoose.model('events', EventSchema);
This is the code which i am trying to fetch the data :
getProductsByClub:function (id, callback){
var model = require("Product");
//model
model .find({'categories.events.e_fk_club_id':id})
.populate({
path:'p_fk_category',
model:'categories',
populate:
{
path:'e_fk_event',
model:'events',
//$match : { e_fk_club_id : id }
}
})
.exec (function(err, doc){
if (err) {
callback(err) ;
} else {
callback(doc) ;
}
})
},
Is There any solution.
Thank you in advance.
I am facing an issue where mongoose query is not populating an array type.
Here is institute schema
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var InstituteSchema = new Schema({
name: String,
address: String,
city: String,
country: String,
zip: String,
owner: { type: mongoose.Schema.ObjectId, ref: 'User' },
teachers: [{type: mongoose.Schema.ObjectId, ref: 'Teacher'}],
categories: [String],
created : { type : Date, default : Date.now }
});
module.exports = mongoose.model('Institute', InstituteSchema);
And here is teacher Schema
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TeacherSchema = new Schema({
education: [{degree: String, instituteName: String}],
dob: Date,
photoUrl: String,
phoneNumber: String,
owner: {type: mongoose.Schema.ObjectId, ref: 'User'},
institutes: [{type: mongoose.Schema.ObjectId, ref: 'Institute'}],
subjects: [{type: mongoose.Schema.ObjectId, ref: 'Subject'}],
created : { type : Date, default : Date.now }
})
module.exports = mongoose.model('Teacher', TeacherSchema);
Here is a method which queries the institute by owner id
exports.mine = function (req, res, next) {
var ObjectId = mongoose.Types.ObjectId;
var userId = new ObjectId(req.user._id);
Institute.find({
owner: userId
}).populate('teachers').exec(function (err, institute) {
if (err) return next(err);
if (!institute) return res.json(401);
res.json(institute);
});
};
I can see from the db that institute has teacher added
db.institutes.find();
{
"_id" : ObjectId("554719a9f5be11c6d4369264"),
"owner" : ObjectId("5547199bf5be11c6d4369263"),
"country" : "USA",
"name" : "Raghvendra Singh",
"address" : "38589 Royal Ann Cmn",
"city" : "Fremont",
"zip" : "94536",
"created" : ISODate("2015-05-04T07:03:05.569Z"),
"categories" : [ "IIT", "Medical" ],
"teachers" : [ ObjectId("55471965f5be11c6d436925f") ],
"__v" : 3
}
But somehow the query method doesn't populate the teachers collection. The weird thing is that i don't even get the collection with object ids and it returns and institute with empty teacher array.
And when i remove the .populate('teachers') from the method call it indeed returns the teacher array with object ids.
I looked at the documentation and i can't see what am i doing wrong.
First you need to change your Model slightly as mention for teachers feild.
teachers: [ { teacher: { type: Schema.ObjectId, ref: "Teacher" } } ]
exports.mine = function (req, res, next) {
var ObjectId = mongoose.Types.ObjectId;
var userId = new ObjectId(req.user._id);
Institute.find({
owner: userId
}).populate('**teachers.teacher**').exec(function (err, institute) {
if (err) return next(err);
if (!institute) return res.json(401);
res.json(institute);
});
};
Then, change your populate parameter to teachers.teacher . It will work