Mongo Reference Schema Collections - mongodb

I’m looking to confirm that my collection structures will correctly allow for the reference I’m trying to make between my collections. Ideally I have a parent collection labeled category, where the child collection is labeled images. I plan on having around 4 documents for my “category” collection and 30 documents for my “images”. All of the documents were going to be uploaded from the command line with a csv file format. If I set up my schemas like I do below and upload the documents with headers matching the fields in the schemas, will I not have an issue with the reference points?
Category
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var categorySchema = new Schema({
name: String,
description: String
});
var Category = mongoose.model(‘Category’, categorySchema);
module.exports = Category;
Images
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var imageSchema = new Schema({
imageUrl: String,
category_id: { type: sechema.ObjectId, ref:"categorySchema"}
});
var Images = mongoose.model('Images', imageSchema);
module.exports = Images;
Here is the layout of my .csv files
category.csv
**name** **description**
Drama Stories about...
images.csv
**imageUrl** **category_id**
www.site.com/image.jpg Drama

Hopefully there can be only one category belonging to an image. One category having many images and each image belongs to only one category.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var categorySchema = new Schema({
name: String,
description: String
images: [{type: mongoose.Schema.Types.ObjectId, ref: 'Images'}]
});
var Category = mongoose.model(‘Category’, categorySchema);
module.exports = Category;
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var imageSchema = new Schema({
imageUrl: String,
category_id: {type: mongoose.Schema.Types.ObjectId, ref:"Category"}
});
var Images = mongoose.model('Images', imageSchema);
module.exports = Images;
Note: You would reference your model not Schema.
Then on you can use mongoose middleware to update your references while saving.
imageSchema.pre('save', function(next){
var Category = require("../models/Category");
var image = this;
Category.findOneAndUpdate(
{_id: {$in: {this.category_id}},
{$push: {images: this._id}},
next
);
});

Related

mongoose model to connect to mongoDB

i have created model for the mongo collection like below. but it was giving me the collection output which saved in mongoDB.
var mongoose = require('mongoose'),
Schema = mongoose.Schema({
name: {
type: String
},
age: {
type: Number
},
})
module.exports = mongoose.model('container', Schema);}
But later when i changed the last line of the code which is
"module.exports = mongoose.model('container', Schema);"
to
"module.exports = mongoose.model('container', Schema, 'container');"
it worked properly. I check the mongoose document they say to use the previous line, then why didn't it worked.
your problem seems to be from using "Schema" as a variable name
var ContainerSchema = new mongoose.Schema({
...
});
and exporting
module.exports = mongoose.model("Container", ContainerSchema);
would work.

Mongoose Schema hasn't been registered for model when populating

I am trying to join 2 collections using the populate method, I have 3 models artists, albums and songs. My mongodb connection is made on server.js.
my artist model is :
var mongoose = require('mongoose');
//var Album = mongoose.model('Album').schema;
console.log(Album);
var artistsSchema = mongoose.Schema({
name:{
type:String,
required:true
},
albums:{
type:[{type:mongoose.Schema.Types.ObjectId,ref :'Album'}]
}
});
var Artist = mongoose.model('Artist',artistsSchema);
module.exports.getArtistsFull = function(callback,limit)
{
Artist.find().limit(1)
.populate({
path:'albums'
,populate :{path:'albums'}
}).exec(callback);
}
And my albums model:
var mongoose = require('mongoose');
var albumsSchema = mongoose.Schema({
name:{
type:String,
required:true
},
songs:{
type:[{type:mongoose.Schema.Types.ObjectId,ref :'Song'}]
}
});
var Album = mongoose.model('Albums',albumsSchema);
module.exports.getAlbumsWithSongs = function(id,callback,limit){
Album.findById(id)
.populate({
path : 'songs',
populate :{path:'songs'}
}).exec(callback);
}
Whenever I call Artist.getArtistsFull function I get an error"Schema hasn't been registered for model Album", I used console.log(Album) on my Album variable inside artist model and I got the functions that were written there, but I don't have access to albumsSchema.
The problem was actually a simple typo
var Album = mongoose.model('Albums',albumsSchema);
changed to
var Album = mongoose.model('Album',albumsSchema);

Improve performance of query of database design sechema in mongodb

I have implemented mongodb schema design for groups where i have a query to get the groups of a specific user. I am thinking to store data as given schema.
For Example
var GroupSchema = new Schema({
name:String,
mememers: [{
userId: { Schema.ObjectId, ref: 'User'}
}]
});
and
var UserSchema = new Schema({
name:String,
email:String,
groups:[{ type:Schema.ObjectId, ref:'Group'}]
});
But i am still confused that what query will be efficient for the query.
var group = Group.find({ "memebers.userId": "***UserId***"});
group.exec(function(err, groups){ });
or
var user = User.findOne({_id:"***userId**"}).populate("groups");
user.exec(function(err, user){ });
Please give me the pro and cons of the both the queries.

Subdocument based on another document

I was wondering if it's possible in Mongoose to have a subdocument based on another document.
Normally I would do something like this:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CountrySchema = new Schema({
name: String,
info: String,
cities : [
{
type: Schema.ObjectId,
ref: 'Ressource'
}
]
});
module.exports = mongoose.model('Country', CountrySchema);
this however create a new document and then references it via the id to the country document. This is not what I want, I want the resource document to be nested inside the country document. How would I do this?
I found that this fixed my problem:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ressourceSchema = require('../ressource/ressource.model');
var CountrySchema = new Schema({
name: String,
info: String,
cities : [
ressourceSchema.schema
]
});
module.exports = mongoose.model('Country', CountrySchema);

mongoose schema multi ref for one property

How to write multi ref for one property of one mongoose schema, like this(but wrong):
var Schema = mongoose.Schema;
var PeopleSchema = new Schema({
peopleType:{
type: Schema.Types.ObjectId,
ref: ['A', 'B'] /*or 'A, B'*/
}
})
You should add string field to your model and store external model name in it, and refPath property - Mongoose Dynamic References
var Schema = mongoose.Schema;
var PeopleSchema = new Schema({
externalModelType:{
type: String
},
peopleType:{
type: Schema.Types.ObjectId,
refPath: 'externalModelType'
}
})
Now Mongoose will populate peopleType with object from corresponding model.
In the current version of Mongoose i still don't see that multi ref possible with syntax like you want. But you can use part of method "Populating across Databases" described here. We just need to move population logic to explicitly variant of population method:
var PeopleSchema = new Schema({
peopleType:{
//Just ObjectId here, without ref
type: mongoose.Schema.Types.ObjectId, required: true,
},
modelNameOfThePeopleType:{
type: mongoose.Schema.Types.String, required: true
}
})
//And after that
var People = mongoose.model('People', PeopleSchema);
People.findById(_id)
.then(function(person) {
return person.populate({ path: 'peopleType',
model: person.modelNameOfThePeopleType });
})
.then(populatedPerson) {
//Here peopleType populated
}
...