How to show relationship between schemas in mongodb like in sql database? - node.js

I have got two models one is "Posts" and another one is "Comments". I want to show relationship between these two models which is a single post has may comments, but i am stuck here. I know how to show these kind of relationship in sql database. Currently i am using mongoose-schema and node js.

To make relation in between Posts and Comments schema
// Comments Schema
var CommentSchema = new Schema({
// your fields
});
module.exports = mongoose.model('Comments', CommentSchema);
// Post schema
var PostSchema = new Schema({
// your fields
comments:[{
type: Schema.Types.ObjectId,
ref:'Comments'
}],
});
// so in comments you will store comments._id values
module.exports = mongoose.model('Posts', PostSchema);

Related

How to associate a mongoose model with the right MongoDB collection in Express.js app?

how to point to particular collection in mongodb using mongoose ORM in express js app .
NA
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var personSchema = new Schema({
name: String,
age: Number
});
module.exports = mongoose.model('person', personSchema);
consider my mongo database have multiple collection ,so how will my above code will point to particular collection.
I'm really sorry my selected answer is not accurate. I can't delete it because it is accepted. The accurate answer to your question is, mongoose.model('person', personSchema); will automatically create a plural lower case version of the model name.In this case, it will automatically create a collection persons in mongoDB if it doesn't exist already.
If you want to override this default behavior, you can do it like this:
var personSchema = new Schema({
name: String,
age: Number
},
{
collection:'people'
});
or
mongoose.model( 'person', personSchema, 'people' ) so you refer to it as person, but collection name will be people
Usually we follow convention of naming the collection plural in mongoDB. For example in MongoDB, we create users table, but use singular in Node.js. So the exports would be:
module.exports = mongoose.model('users',UserSchema)
And in other script, we require it as follows:
const User=require('<pathToModel>/user')
This means we are referring to the model as User, it is based on UserSchema and the collection associated with this is users
In your code, you could do this:
module.exports = mongoose.model('person', personSchema);
If you have a specific collection you want documents based on a specific model to go into, you can use mongoose.model('person', personSchema, collection).
Or, you could name the desired associated collection in the Schema definition:
var dataSchema = new Schema({..}, { collection: 'data' });
https://mongoosejs.com/docs/guide.html

Mongoose nested schema vs nested models

What is the difference between nesting schema in schema (subdocuments) vs creating two separate models and referring to them, What about their performance?
subdocuments:
const postSchema = new Schema({
title: String,
content: String
});
const userSchema = new Schema({
name: String,
posts: [postSchema]
});
module.export = mongoose.model('User', userSchema);
nested models (Populating by reference):
const postSchema = new Schema({
title: String,
content: String,
author: { type: String, ref: 'User' }
});
module.export = mongoose.model('Post', postSchema);
const userSchema = new Schema({
name: String,
posts: [{ type: Schema.Types.ObjectId, ref: 'Post'}]
});
module.export = mongoose.model('User', userSchema);
Edit: This is not a duplicate question.
In this question: Mongoose subdocuments vs nested schema - mongoose subdocuments and nested schema is exactly the same.
BUT nested models creating a separate collection in database.
My question is what is diffrence in nested schema vs nested models, not subdocuments vs nested schema.
When using subdocuments, you actually have a copy of the data within your parent-document, wich allows you to get all the document + sub-document-data in a single query.
When using "nested models" you're not really nesting them, but referencing from the parent-model to the child-model. In this case you have to use population, which means you can't get all the data in a single query.
In short: subdocuments actually nest the data, and your "nested models" only reference them via their id

Structuring a list of favourites with MongoDB & Mongoose?

I am starting to use mongo, and I would like to create a schema for items that a user has 'favourited'. My current code, using mongoose and node.js looks at follows:
// load the things we need
var mongoose = require('mongoose');
// define the schema for our favourites model
var favouritedItemsSchema = mongoose.Schema({
userId : Number,
item : [{
itemId : Number,
addedDate : Date
}]
});
// create the model for favourites and expose it to our app
module.exports = mongoose.model('Favourites', favouritedItemsSchema);
Coming from a relational DB background, I am wondering whether the above approach would represent a suitable NoSQL DB design approach? If not, can someone show me what would be something that fits the design philosophy?
Yes, you are right, the relational and the NoSQL design approach are totally different.
Where you have 10 tables for example in RDBMS, you could have only 2 or 3 collections in mongo. That's because the way we create relations between objects is far more interesting in NoSQL (subdocument, arrays, etc..).
Here is one solution for your problem, reusing an existing User collection.
// load the things we need
var mongoose = require('mongoose');
// define the schema for our model
var userSchema = mongoose.Schema({
username: string,
favourites: [{
id: Schema.Types.ObjectId,
addedDate: Date
}]
});
// export model
module.exports = mongoose.model('User', userSchema);

One-To-Many relation in MongoDB

At the moment I am looking at mongoDB. I try to implement a simple one-to-many relation using nodejs and mongoose:
Model/Schema User:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var UserSchema = new Schema({
name: String
});
module.exports = mongoose.model('User', UserSchema);
Model/Schema Article:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ArticleSchema = new Schema({
name: {
type: String,
required: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
module.exports = mongoose.model('Article', ArticleSchema);
So my question, now:
How can I get all Users including its Articles?
Do I really have to add a ref to my UserScheme, too? What is the best-practice in an one-to-many relation like this? Is there something like a join in mongodb?
One User has many Articles - an Article belongs to one User.
Calling something like /user/:user_id , I want to receive the user with _id=user_id containing all of his articles.
That is the most horrible idea, for various reasons.
First, there is a 16MB BSON document size limit. You simply can not put more into a document. Embedding documents is rather suited for "One-to-(VERY-)Few" relationships than for a "One-to-Many".
As for the use case: What is your question here? It is
For a given user, what are the articles?
REST wise, you should only return the articles when /users/:id/articles is GETed and the articles (and only the articles) should be returned as a JSON array.
So, your model seems to be natural. As for the user:
{
_id: theObjectId,
username: someString
…
}
and an article should look like this:
{
_id: articleIdOrSlugOrWhatever,
authors: [theObjectId],
// or author: theObjectId
retention: someISODate,
published: someOtherISODate
}
So when your REST service is called for /users/:id you'd simply look up
var user = db.users.findOne({_id:id})
And when /users/:id/articles is called, you'd lookup
var articles = db.articles.find({author:id})
Problem solved in a scalable way, adhering to REST principles.

Mongoose schemas and collections

Hi everyone this is the first time I ask a question in here,
I'm very new into the MEAN stack and by now I'm trying to develop an application using it. As I understand in mongodb an Schema (Database) can have one or more collections (Tables(?)), when I'm using mongoose I define a Song model and an Artist model:
For Song:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var songSchema = new Schema({
songName: { type: String },
songArtist: [{type : Schema.Types.ObjectId, ref : 'Artist'}]
});
module.exports = mongoose.model('Song', songSchema);
For artist:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var artistSchema = new Schema({
artistName: { type: String }
});
module.exports = mongoose.model('Artist', artistSchema);
My app.js looks like this:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/song', function(err, res) {
if(err) throw err;
console.log('Connected to Database');
});
var models = require('./models/song')(app, mongoose);
The issue with this is, as I understand and saw, that I'm creating 2 databases/schemas while I want to Create one database/schema and have this two collections in there:
SongDatabase:
--- Song
--- Artist
How should I do it in this case with my mongoose models/controllers and my app.js? Thanks in advance :)
I solved all my doubts taking a look into this tutorial, as you can see in here they implement two collections within one database (My inicial concern). Once you are connected to the database and you perform a post to the collection you want, in this case thread or post, it will create the collection into mongodb.
The issue there is that your connection string is mongodb://localhost/song
Song becomes your DB, and within Song you should be able to see two collections
- SongS
- ArtistS
Posible solutions: Flush the database, drop all. Start clean and check what your application is doing. Use another name for the DB

Resources