Before all, not exists JOIN here! Basically is saved the _id
from one collection to another collection ( {type: mongoose.Schema.Types.ObjectId,ref:'NameOfSchema'}
).Where the data related it select with the populate()
method.
The ideia of the example
Will be a system that allows Users
to register and that these users can create Posts
required dependencies
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"mongoose": "^5.7.5",
"nodemon": "^1.19.4"
├── index.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
// middlewares
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
mongoose.connect('mongodb://localhost:27017/relationships',{
useNewUrlParser: true,
useUnifiedTopology: true
})
// routes
app.use(require('./app/routes'));
app.listen(3000, () => console.log('server on!'));
├── models
└── user.js
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name :{
type:String,
required: '{PATH} is required!'
},
bio: {
type:String
},
website:{
type:String
},
posts : [
{type: mongoose.Schema.Types.ObjectId,ref:'Post'}
]
},{
timestamps: true
})
module.exports = mongoose.model('User',UserSchema);
├── models
└── post.js
const mongoose = require('mongoose');
const PostSchema = new mongoose.Schema({
title:{
type:String,
required: '{PATH} is required!'
},
subtitle :{
type: String
},
user :{
type:mongoose.Schema.Types.ObjectId,
ref:'User'
}
},{
timestamps:true
})
module.exports = mongoose.model('Post',PostSchema);
└── user.js ( controller )
const User = require('../../models/user');
module.exports = {
create : async (req, res) =>{
const { name, bio, website } = req.body;
const user = await User.create({
name,
bio,
website
})
return res.send(user)
},
find : async (req, res) => {
const user = await User.find()
return res.send(user)
},
postsByUser : async (req, res) => {
const { id } = req.params;
const user = await User.findById(id).populate('posts');
res.send(user.posts);
}
}
notice that const user = await User.findById(id).populate('posts')
is equivalent to :
user.posts.forEach(async element => {
const post = await Post.findById(element);
console.log(post);
});
└── post.js ( controller )
const Post = require('../../models/post');
const User = require('../../models/user');
module.exports = {
create : async (req, res) => {
console.log(req.params);
user = req.params;
id = user.id;
const { title, subtitle} = req.body;
const post = await Post.create({
title,
subtitle,
user:id
});
await post.save();
const userById = await User.findById(id);
userById.posts.push(post);
await userById.save();
return res.send(userById);
},
userByPost : async (req,res)=>{
const { id } = req.params;
const userByPost = await Post.findById(id).populate('user');
res.send(userByPost);
}
}
└── routes.js
const express = require('express');
const router = new express.Router;
const User = require('./controllers/user/user');
const Post = require('./controllers/post/post');
router.get('/',(req,res)=>res.send('ok'));
// user routes
router.post('/user/create',User.create);
router.post('/user/find',User.find);
router.post('/user/find/post/:id', User.postsByUser);
// post routes
router.post('/post/create/:id', Post.create);
router.post('/post/populate/:id',Post.userByPost);
module.exports = router;
configure └── package.json
to use nodemon in your project, set "start" key in "scripts",passing the nodemon command and the application root filename.
"scripts": {
"start": "nodemon index.js"
},
after this, run command "npm start" in your terminal and the application will restart the server every time any files of your project are changed, making development more productive.
Final Result
thanks for everything!
😄
Top comments (17)
My answer would be: don't. If you need relationships, go for a relational database. IMHO NoSQL databases are for totally different purpose: they're for data, where you don't care about the structure, like logs, analytics data etc. In case you need a structure, NoSQL database is a bad idea because the database doesn't give you any certainty about how the data is structured.
Thanks for your reply.I know about this, but i just only wanted to show that possible create relationships with NoSQL,even though it's not the best solution for building relationships. 🤘 🤘 🤘
Sure thing! I don't say your article is bad, it helps a lot! Just wanted to point out my concerns 😄
Awesome tutorial!
Just adding how I managed to work in a slightly different way.
My 'create' function from my post controller looks like this:
Could you please add request examples?
I added a gif, showing how the routes work. Thanks for the feedback! 😄
Thank you very much! :) cool post
🤘 🤘 🤘
Hi, am having an issue with my mongoose command installation on windows terminal: npm install --save mongoose
each time i try to install i get a node file opened from vnode.exe.
any help would be appreciated
Just do npm install mongoose, the save is not needed anymore since versión 5.x.x I think. Some one correct me if im wrong.
router.post('/user/find',User.find); this line not working
Hello, I know this is a post from 2019 but I am following in 2021 - having an issue with the create Post POST - can you show us a POSTMAN example of what ID you used to POST the post?
Thank you, this was excellent.
also why did you use the router.post request on user/find and user/find/post/:id? Just curious, otherwise great article.
O
Thank you sooo much! mongose docs isn't enough for this :(
While an interesting exercise, anyone looking production solutions, reconsider.
Never reinvent the wheel.
If you need RDBS, choose RDBS.
Don't shoehorn RDBS into a document-oriented DBS.
Thanks for your reply! Yes, it is for teaching purposes only, when you want to create relationships, I would not recommend using NoSQL. 🤘 🤘 🤘