Difference between revisions of "Mongo DB usage in Node"
(Created page with "Category:Node.js Category:MongoDb == Setting up our database == Right, next up we are going to setup our database. We’re going to use mongodb with mongoose. yarn...") |
|||
| Line 1: | Line 1: | ||
[[Category:Node.js]] | [[Category:Node.js]] | ||
[[Category:MongoDb]] | [[Category:MongoDb]] | ||
| − | + | <div style="float:right;">__TOC__</div> | |
== Setting up our database == | == Setting up our database == | ||
Revision as of 08:38, 7 November 2018
Setting up our database
Right, next up we are going to setup our database. We’re going to use mongodb with mongoose.
yarn add mongoose
or
npm i mongoose
in index.js
const hapi = require('hapi');
const mongoose = require('mongoose');
The next final ingredient related to our database is mlab. Instead of running mongo on our local computer, we are gonna use a cloud provider like mlab. And finally create a user for the database. That will be all we will be editing on mlab.
mongoose.connect('mongodb://<DBUserName>:<DbPassWord>@ds245680.mlab.com:<Port>/<DbName>')
mongoose.connection.once('open', ()=> {
console.log('connected to database');
})
or
mongoose.connect('mongodb://<DBUserName>:<DbPassWord>@ds245680.mlab.com:<Port>/<DbName>')
.then() => console.log('connected to database')
.catch() => console.error('Could not connect to database', err);
Schema
it's not part of mongoDb. It's related with mongoose
const courseSchema = new mongoose.Schema({
name: String,
author: String,
tags:[ String ],
date: Date, // or with a default value -> date: {type:Date, default: Date.now }
isPublished: Boolean
});
Schema Types
- String
- Number
- Date
- Buffer
- Boolean
- ObjectID
- Array
Schema to Model
const Course = mongoose.model('Course', courseSchema);
using model
const course = new Course({
name : 'Node.js Course',
author : 'Ali',
tags : ['node', 'backend'],
isPublished : true
});
Save object to DB
async function createCourse(){
const courseSchema = new mongoose.Schema({
name: String,
author: String,
tags:[ String ],
date: Date, // or with a default value -> date: {type:Date, default: Date.now }
isPublished: Boolean
});
const result = await course.save();
console.log(result);
}
createCourse();
Query Database
async function getCourses(){
const courses = await Course.find();
// const courses = await Course.find({ author: 'Ali', isPublished: true}); // with criteria
console.log(courses);
}
getCourses();
a little bit more complex query
async function getCourses(){
const courses = await Course
.find({ author: 'Ali', isPublished: true})
.limit(10)
.sort({ name: 1}) // desc : -1
.select({name:1, tags:1});
console.log(courses);
}
getCourses();
Comparison Operators
- eq : equal
- ne : not equal
- gt : greater than
- gte : greater than or equal to
- lt : less than
- lte : less than or equal to
- in : in
- nin : not in
async function getCourses(){
const courses = await Course
.find({ price: {$gt: 10} }) // greater than
// .find({ price: {$gt: 10, $lt:20} }) // between 10 and 20
// .find({ price: {$in: [10,15, 20]} }) // in 10,15 and 20
.limit(10)
.sort({ name: 1}) // desc : -1
.select({name:1, tags:1});
console.log(courses);
}
getCourses();
Logical Operators
- or
- and
async function getCourses(){
const courses = await Course
.find()
.or([{author:'Ali'},{ isPublished:true}]) //-> author is Ali or published
.limit(10)
.sort({ name: 1}) // desc : -1
.select({name:1, tags:1});
console.log(courses);
}
getCourses();
Regular Expressions
- ^ : starts with /^Ali/
- $ : ends with /Iybar$/
- i : case insensitive /Iybar$/i
- .*something.* : Contains /.*yba.*/
async function getCourses(){
const courses = await Course
.find( {author:/^Ali/ })
.limit(10)
.sort({ name: 1}) // desc : -1
.select({name:1, tags:1});
console.log(courses);
}
getCourses();
Count
async function getCourses(){
const courses = await Course
.find( {author:/^Ali/ })
.limit(10)
.sort({ name: 1}) // desc : -1
.count()
console.log(courses);
}
getCourses();
Paging
async function getCourses(){
const pageNumber =2;
const pageSize = 10;
const courses = await Course
.find( {author:/^Ali/ })
.skip(pageNumber -1) * pageSize)
.limit(pageSize)
.sort({ name: 1}) // desc : -1
.select({name:1, tags:1});
console.log(courses);
}
getCourses();
Update with QueryFirst Approach
async function updateCourses(id){
const courses = await Course.findById(id);
if((!course) return;
course.isPublished = true;
course.author = 'Another Author';
// Alternatively
// course.set({
// isPublished:true,
// author:'Another Author'
// });
const result = await course.save();
console.log(courses);
}
updateCourses('1234-01-12123....');
Update with Update First Approach
async function updateCourses(id){
const result = await Course.update({_id:id}, { // for more records ({ isPublished:false })
$set: {
author:'Veli',
isPublished:false
}
});
console.log(result);
}
updateCourses('1234-01-12123....');
FindByIdAndUpdate
This returns the original object before the update
async function updateCourses(id){
const result = await Course.findByIdAndUpdate (id, { // for more records ({ isPublished:false })
$set: {
author:'Veli',
isPublished:false
}
});
console.log(result);
}
updateCourses('1234-01-12123....');
In order to get updated object we pass another arguement { new : true}
async function updateCourses(id){
const result = await Course.findByIdAndUpdate (id, { // for more records ({ isPublished:false })
$set: {
author:'Veli',
isPublished:false
}
},{ new : true});
console.log(result);
}
updateCourses('1234-01-12123....');
Remove a document
async function removeCourses(id){
const result = await Course.deleteOne({ _id:id})
console.log(result);
}
removeCourses('1234-01-12123....');
it returns null if there is no such record exists
Remove many documents
async function removeCourses(id){
const result = await Course.deleteMany({ isPublished:false})
console.log(result);
}
removeCourses('1234-01-12123....');
Mongoose Data Validation
const courseSchema = new mongoose.Schema({
name: { type: String, required:true},
author: String,
tags:[ String ],
date: Date, // or with a default value -> date: {type:Date, default: Date.now }
isPublished: Boolean
});
if the data to be saved is not valid promise returns error.
Manually Triggering Validation
async function createCourse(){
const courseSchema = new mongoose.Schema({
author: String,
tags:[ String ],
date: Date, // or with a default value -> date: {type:Date, default: Date.now }
isPublished: Boolean
});
await course.validate();
// or
course.validate((err) => {
if(err) {
.... do something
}
});
console.log(result);
}
createCourse();
Built-in Validation
name: {
type: String,
required:true,
minlength:5,
maxlength:255,
match:/regex/,
enum: ['web', 'mobile', 'network']
},
price:{
type:Number,
min:10,
max:200
}
Custom Validators
const courseSchema = new mongoose.Schema({
name: { type: String, required:true},
author: String,
tags:[ String ],
date: Date, // or with a default value -> date: {type:Date, default: Date.now }
isPublished: Boolean
price: {
type:Number,
required:function(){ return this.isPublished;} // it is required if isPublished -> can't use arrow function here because of this
}
});
if the data to be saved is not valid promise returns error.
tags: {
type: Array,
validate:{
validator: function(v) {
return v && v.length > 0;
},
message:'Must be greater than 0'
}
}
Async Validator
isAsync : true and callbacks
tags: {
type: Array,
validate:{
isAsync : true,
validator: function(v, callback) {
setTimeout(()=> {
// do something
const result = v && v.length > 0;
callback(result)
}, 1000);
},
message:'Must be greater than 0'
}
}
Validation Errors
try {
const result = await course.save();
console.log(result);
}
catch (ex) {
for (field in ex.errors)
console.log(ex.errors[field]);
}
Schema Type Options
string
- lowercase: true
- uppercase: true
- trim: true
name: {
type: String,
required:true,
minlength:5,
maxlength:255,
match:/regex/,
enum: ['web', 'mobile', 'network'],
lowercase : true
},
getter and setter
- get: v=> Math.round(v)
- set: v=> Math.round(v)