Difference between revisions of "MongoDB and NodeJs"
(→NodeJs-Mongo) |
(→Docker Compose - MongoDb) |
||
(18 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=[[MongoDB]] = | =[[MongoDB]] = | ||
+ | |||
+ | ==Docker Compose - MongoDb== | ||
+ | docker-compose.yml | ||
+ | <source> | ||
+ | version: "2" | ||
+ | services: | ||
+ | mongo: | ||
+ | image: mongo | ||
+ | ports: | ||
+ | - "27017:27017" | ||
+ | </source> | ||
+ | |||
+ | To run the two dockers using the compose file execute the command: | ||
+ | |||
+ | <source> | ||
+ | $ docker-compose up | ||
+ | </source> | ||
+ | |||
+ | Lets test: | ||
+ | <source> | ||
+ | $ docker ps | ||
+ | CONTAINER ID IMAGE COMMAND... | ||
+ | 9a47337d30fe easynodeauthentication_web "npm start"... | ||
+ | c0f31757662b mongo "docker..."... | ||
+ | $ docker exec -it c0f31757662b /bin/bash | ||
+ | $ mongo | ||
+ | MongoDB shell version v3.4.10 | ||
+ | connecting to: mongodb://127.0.0.1:27017 | ||
+ | MongoDB server version: 3.4.10 | ||
+ | Welcome to the MongoDB shell. | ||
+ | > show dbs | ||
+ | admin 0.000GB | ||
+ | local 0.000GB | ||
+ | passport 0.000GB | ||
+ | > use passport | ||
+ | switched to db passport | ||
+ | > show collections | ||
+ | users | ||
+ | > db.users.find({}) | ||
+ | { "_id" : ObjectId("5a1f982615336e0010c38dd1"), "local" : { "password" : "$2a$08$rDBEIW7FBnH2LPk6E9ptFuv.J71/HrBZkQfdPjpiWDK/FUMHTto4y", "email" : "johndoe@example.com" }, "__v" : 0 } | ||
+ | </source> | ||
+ | |||
+ | https://medium.com/@kahana.hagai/docker-compose-with-node-js-and-mongodb-dbdadab5ce0a | ||
=[[NodeJs]]= | =[[NodeJs]]= | ||
Line 24: | Line 67: | ||
>brew services start mongo #start/stop/status | >brew services start mongo #start/stop/status | ||
</source> | </source> | ||
+ | |||
+ | '''From the Visual Studio Code Setup page:''' | ||
+ | <source> | ||
+ | |||
+ | Tip: If you want to run VS Code from the terminal by simply typing 'code', VS Code has a command, Shell Command: Install 'code' command in PATH, to add 'code' to your $PATH variable list. | ||
+ | |||
+ | After installation, launch VS Code. '''Now open the Command Palette (F1 or ⇧+⌘+P on Mac) and type shell command to find the Shell Command: Install 'code' command in PATH command.''' | ||
+ | |||
+ | After executing the command, restart the terminal for the new $PATH value to take effect. You'll be able to simply type 'code .' in any folder to start editing files in that folder. | ||
+ | </source> | ||
+ | |||
=NodeJs-Mongo= | =NodeJs-Mongo= | ||
+ | ==Create a project== | ||
<source> | <source> | ||
$ mkdir users => cd users | $ mkdir users => cd users | ||
Line 55: | Line 110: | ||
+ | ==package.json - project details and depencies file== | ||
+ | '''package.json file:''' | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | { | ||
+ | "name": "users", | ||
+ | "version": "1.0.0", | ||
+ | "description": "", | ||
+ | "main": "index.js", | ||
+ | "scripts": { | ||
+ | "test": "mocha" | ||
+ | }, | ||
+ | "author": "", | ||
+ | "license": "ISC", | ||
+ | "dependencies": { | ||
+ | "mocha": "^5.2.0", | ||
+ | "mongoose": "^5.3.10", | ||
+ | "nodemon": "^1.18.6", | ||
+ | "request": "^2.88.0" | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
==Mocha - Unit Test== | ==Mocha - Unit Test== | ||
Mocha is most famous test framework for javascript.. | Mocha is most famous test framework for javascript.. | ||
− | + | ===Creating data on MongoDb/Test=== | |
'''test/create_test.js(test file):''' | '''test/create_test.js(test file):''' | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
Line 71: | Line 147: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ''' | + | '''test/create_test.js(another sample): ''' |
+ | <syntaxhighlight lang="javascript"> | ||
+ | const assert = require('assert'); | ||
+ | const User = require('../src/user'); | ||
+ | |||
+ | |||
+ | describe('Creating records',()=>{ | ||
+ | it('saves a user',(done)=>{ //<------------ 1.callback | ||
+ | const joe = new User({ name: 'Joe'}); | ||
+ | |||
+ | //joe.save(); | ||
+ | joe.save() | ||
+ | .then((result) => { | ||
+ | //Has joe been saved successfully? | ||
+ | assert(!joe.isNew); | ||
+ | done(); //<------------------- 2.callback: we should use | ||
+ | }).catch((err) => { | ||
+ | console.log('Error'); | ||
+ | }); | ||
+ | |||
+ | }); | ||
+ | }); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Search/Find Record on Mongo=== | ||
+ | '''reading_test.js''': | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | const assert = require('assert'); | ||
+ | const User = require('../src/user'); | ||
+ | |||
+ | describe('Reading users out of the database', ()=>{ | ||
+ | let joe; | ||
+ | |||
+ | beforeEach((done)=>{ | ||
+ | joe=new User({name:'Joe'}); | ||
+ | joe.save() | ||
+ | .then((result) => { | ||
+ | done(); | ||
+ | }).catch((err) => { | ||
+ | console.log('Error..'); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | it('finds all users with a name of joe',(done)=>{ | ||
+ | User.find({ name:'Joe' }) | ||
+ | .then((users)=>{ | ||
+ | console.log(users); | ||
+ | assert(users[0]._id.toString() === joe._id.toString()); | ||
+ | done(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | it('find a user with a particular id', (done)=>{ | ||
+ | User.findOne({_id:joe._id}) | ||
+ | .then((user)=>{ | ||
+ | assert(user.name === 'Joe'); | ||
+ | done(); | ||
+ | }); | ||
+ | }); | ||
+ | }); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Deleting/removing records=== | ||
+ | |||
+ | '''delete_test.js''' | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | const assert = require('assert'); | ||
+ | const User = require('../src/user'); | ||
+ | |||
+ | describe('Deleting a user',()=>{ | ||
+ | let joe; | ||
+ | |||
+ | beforeEach((done)=>{ | ||
+ | joe = new User({name:'Joe'}); | ||
+ | joe.save() | ||
+ | .then((result) => { | ||
+ | done(); | ||
+ | }).catch((err) => { | ||
+ | console.log('delete:error in beforeEach!'); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | it('model instance remove',(done)=>{ | ||
+ | joe.remove()//it remove joe instance that we created in beforeEach method | ||
+ | .then(() => User.findOne({name:'Joe'}))//to test that the object deleted, it should return null | ||
+ | .then((user)=>{//then: they work sequentially | ||
+ | assert(user === null); | ||
+ | done(); | ||
+ | }) | ||
+ | ; | ||
+ | }); | ||
+ | |||
+ | it('class method remove',(done)=>{ | ||
+ | //remove a bunch of records with some given criteria | ||
+ | User.remove({ name:'Joe' }) | ||
+ | .then(()=>User.findOne({name:'Joe'})) | ||
+ | .then((user)=>{ | ||
+ | assert(user === null); | ||
+ | done(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | it('class method findAndRemove',(done)=>{ | ||
+ | User.findOneAndRemove({name:'Joe'}) | ||
+ | .then(()=>User.findOne({name:'Joe'})) | ||
+ | .then((user)=>{ | ||
+ | assert(user === null); | ||
+ | done(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | it('class method findByIdAndRemove',(done)=>{ | ||
+ | User.findByIdAndRemove(joe._id) | ||
+ | .then(()=>User.findOne({name:'Joe'})) | ||
+ | .then((user)=>{ | ||
+ | assert(user === null); | ||
+ | done(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | |||
+ | }); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Updating records === | ||
+ | '''update_test.js''': | ||
+ | <syntaxhighlight lang="javascript"> | ||
+ | const assert=require('assert'); | ||
+ | const User = require('../src/user'); | ||
+ | |||
+ | describe('Updating records',()=>{ | ||
+ | let joe; | ||
+ | |||
+ | beforeEach((done)=>{ | ||
+ | joe = new User({name:'Joe'}); | ||
+ | joe.save() | ||
+ | .then(()=>done()); | ||
+ | }); | ||
+ | |||
+ | function assertName(operation, done){ | ||
+ | operation | ||
+ | .then(()=>User.find({})) | ||
+ | .then((users)=>{ | ||
+ | assert(users.length === 1); | ||
+ | assert(users[0].name === 'Alex'); | ||
+ | done(); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | //set and save: when you update more record(emaıl, phone, address), | ||
+ | //like a transactional update, | ||
+ | //we can update all data, and then save all. | ||
+ | it('instance type using set n save',(done)=>{ | ||
+ | console.log(joe); | ||
+ | joe.set('name','Alex'); | ||
+ | assertName(joe.save(),done); | ||
+ | console.log(joe); | ||
+ | }); | ||
+ | |||
+ | //update : directly update | ||
+ | it('A model instance can update',(done)=>{ | ||
+ | assertName(joe.update({name:'Alex'}),done); | ||
+ | }); | ||
+ | |||
+ | it('A model class can update', (done)=>{ | ||
+ | assertName( | ||
+ | User.update({name:'Joe',name:'Alex'}), | ||
+ | done | ||
+ | ); | ||
+ | }); | ||
+ | |||
+ | it('A model class can update one record', (done)=>{ | ||
+ | assertName( | ||
+ | User.findOneAndUpdate({name:'Joe',name:'Alex'}), | ||
+ | done | ||
+ | ); | ||
+ | }); | ||
+ | |||
+ | it('A model class can find a record with an Id and update',(done)=>{ | ||
+ | assertName( | ||
+ | User.findByIdAndUpdate(joe._id,{name:'Alex'}), | ||
+ | done | ||
+ | ); | ||
+ | }); | ||
+ | |||
+ | }); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Run the test : npm run test=== | ||
+ | <source> | ||
+ | $ npm run test | ||
+ | </source> | ||
+ | |||
+ | ==Automating Test== | ||
+ | "test": "nodemon --exec 'mocha -R min'" : formats and clear the output | ||
+ | If I change the code, it runs test again for changes. | ||
+ | |||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
{ | { | ||
Line 79: | Line 351: | ||
"main": "index.js", | "main": "index.js", | ||
"scripts": { | "scripts": { | ||
− | "test": "mocha" | + | "test": "nodemon --exec 'mocha -R min'" |
}, | }, | ||
"author": "", | "author": "", | ||
Line 90: | Line 362: | ||
} | } | ||
} | } | ||
+ | |||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | =MongoDB with Node and Express= | ||
+ | '''Node''':Engine for running JavaScript outside of a browser environment. Can work with HTTP requests. | ||
+ | |||
+ | '''Express''':Framework to simplify working with HTTP requests. | ||
+ | http://rasimsen.com/images/node-express-mongo-rest-api.png | ||
+ | |||
+ | |||
+ | ==Create a new project== | ||
<source> | <source> | ||
− | $ npm | + | $ mkdir muber |
+ | $ cd muber | ||
+ | $ npm init | ||
+ | $ code . #to open in a editor(atom, code) | ||
</source> | </source> | ||
+ | to install some dependencies.. | ||
+ | you can use '''SuperTest''' which is can be used to test HTTP endpoints. | ||
+ | <source> | ||
+ | $ sudo npm install --save nodemon mongoose express mocha | ||
+ | $ sudo npm install --save supertest #you can use SuperTest which is can be used to test HTTP endpoints. | ||
+ | $ sudo npm install --save body-parser #Parse incoming request bodies in a middleware before your handlers, available under the req.body property. | ||
+ | </source> | ||
+ | ==Environment Definition== | ||
− | + | node-express-mongo-environment-variable.png | |
− | |||
− | |||
− | |||
− | |||
− | |||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> |
Latest revision as of 16:38, 5 July 2019
MongoDB
Docker Compose - MongoDb
docker-compose.yml
version: "2"
services:
mongo:
image: mongo
ports:
- "27017:27017"
To run the two dockers using the compose file execute the command:
$ docker-compose up
Lets test:
$ docker ps
CONTAINER ID IMAGE COMMAND...
9a47337d30fe easynodeauthentication_web "npm start"...
c0f31757662b mongo "docker..."...
$ docker exec -it c0f31757662b /bin/bash
$ mongo
MongoDB shell version v3.4.10
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
Welcome to the MongoDB shell.
> show dbs
admin 0.000GB
local 0.000GB
passport 0.000GB
> use passport
switched to db passport
> show collections
users
> db.users.find({})
{ "_id" : ObjectId("5a1f982615336e0010c38dd1"), "local" : { "password" : "$2a$08$rDBEIW7FBnH2LPk6E9ptFuv.J71/HrBZkQfdPjpiWDK/FUMHTto4y", "email" : "johndoe@example.com" }, "__v" : 0 }
https://medium.com/@kahana.hagai/docker-compose-with-node-js-and-mongodb-dbdadab5ce0a
NodeJs
Installation
We will install :
- MongoDb
- Node
- Robomongo - editor
brew - package manager can be used on MacOs
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Mongo Installation:
>brew install mongo
>mongod
>sudo mkdir -p /data/db
>sudo chown -Rv rasimsen /data/db
>brew services start mongo #start/stop/status
From the Visual Studio Code Setup page:
Tip: If you want to run VS Code from the terminal by simply typing 'code', VS Code has a command, Shell Command: Install 'code' command in PATH, to add 'code' to your $PATH variable list.
After installation, launch VS Code. '''Now open the Command Palette (F1 or ⇧+⌘+P on Mac) and type shell command to find the Shell Command: Install 'code' command in PATH command.'''
After executing the command, restart the terminal for the new $PATH value to take effect. You'll be able to simply type 'code .' in any folder to start editing files in that folder.
NodeJs-Mongo
Create a project
$ mkdir users => cd users
$ mkdir src
$ mkdir test
$ npm install request --save #url için
$ npm install --save mocha nodemon mongoose
mocha: unit test nodemon: mongoose : mongo db driver
src/user.js:
const mongoose=require('mongoose');
const Schema=mongoose.Schema;
const UserSchema = new Schema({
name:String
});
const User = mongoose.model('User',UserSchema);
module.exports = User;
package.json - project details and depencies file
package.json file:
{
"name": "users",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC",
"dependencies": {
"mocha": "^5.2.0",
"mongoose": "^5.3.10",
"nodemon": "^1.18.6",
"request": "^2.88.0"
}
}
Mocha - Unit Test
Mocha is most famous test framework for javascript..
Creating data on MongoDb/Test
test/create_test.js(test file):
const assert = require('assert');
describe('Creating records',()=>{
it('saves a user',()=>{
assert(1+1 ===2);
});
});
test/create_test.js(another sample):
const assert = require('assert');
const User = require('../src/user');
describe('Creating records',()=>{
it('saves a user',(done)=>{ //<------------ 1.callback
const joe = new User({ name: 'Joe'});
//joe.save();
joe.save()
.then((result) => {
//Has joe been saved successfully?
assert(!joe.isNew);
done(); //<------------------- 2.callback: we should use
}).catch((err) => {
console.log('Error');
});
});
});
Search/Find Record on Mongo
reading_test.js:
const assert = require('assert');
const User = require('../src/user');
describe('Reading users out of the database', ()=>{
let joe;
beforeEach((done)=>{
joe=new User({name:'Joe'});
joe.save()
.then((result) => {
done();
}).catch((err) => {
console.log('Error..');
});
});
it('finds all users with a name of joe',(done)=>{
User.find({ name:'Joe' })
.then((users)=>{
console.log(users);
assert(users[0]._id.toString() === joe._id.toString());
done();
});
});
it('find a user with a particular id', (done)=>{
User.findOne({_id:joe._id})
.then((user)=>{
assert(user.name === 'Joe');
done();
});
});
});
Deleting/removing records
delete_test.js
const assert = require('assert');
const User = require('../src/user');
describe('Deleting a user',()=>{
let joe;
beforeEach((done)=>{
joe = new User({name:'Joe'});
joe.save()
.then((result) => {
done();
}).catch((err) => {
console.log('delete:error in beforeEach!');
});
});
it('model instance remove',(done)=>{
joe.remove()//it remove joe instance that we created in beforeEach method
.then(() => User.findOne({name:'Joe'}))//to test that the object deleted, it should return null
.then((user)=>{//then: they work sequentially
assert(user === null);
done();
})
;
});
it('class method remove',(done)=>{
//remove a bunch of records with some given criteria
User.remove({ name:'Joe' })
.then(()=>User.findOne({name:'Joe'}))
.then((user)=>{
assert(user === null);
done();
});
});
it('class method findAndRemove',(done)=>{
User.findOneAndRemove({name:'Joe'})
.then(()=>User.findOne({name:'Joe'}))
.then((user)=>{
assert(user === null);
done();
});
});
it('class method findByIdAndRemove',(done)=>{
User.findByIdAndRemove(joe._id)
.then(()=>User.findOne({name:'Joe'}))
.then((user)=>{
assert(user === null);
done();
});
});
});
Updating records
update_test.js:
const assert=require('assert');
const User = require('../src/user');
describe('Updating records',()=>{
let joe;
beforeEach((done)=>{
joe = new User({name:'Joe'});
joe.save()
.then(()=>done());
});
function assertName(operation, done){
operation
.then(()=>User.find({}))
.then((users)=>{
assert(users.length === 1);
assert(users[0].name === 'Alex');
done();
});
}
//set and save: when you update more record(emaıl, phone, address),
//like a transactional update,
//we can update all data, and then save all.
it('instance type using set n save',(done)=>{
console.log(joe);
joe.set('name','Alex');
assertName(joe.save(),done);
console.log(joe);
});
//update : directly update
it('A model instance can update',(done)=>{
assertName(joe.update({name:'Alex'}),done);
});
it('A model class can update', (done)=>{
assertName(
User.update({name:'Joe',name:'Alex'}),
done
);
});
it('A model class can update one record', (done)=>{
assertName(
User.findOneAndUpdate({name:'Joe',name:'Alex'}),
done
);
});
it('A model class can find a record with an Id and update',(done)=>{
assertName(
User.findByIdAndUpdate(joe._id,{name:'Alex'}),
done
);
});
});
Run the test : npm run test
$ npm run test
Automating Test
"test": "nodemon --exec 'mocha -R min'" : formats and clear the output
If I change the code, it runs test again for changes.
{
"name": "users",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "nodemon --exec 'mocha -R min'"
},
"author": "",
"license": "ISC",
"dependencies": {
"mocha": "^5.2.0",
"mongoose": "^5.3.10",
"nodemon": "^1.18.6",
"request": "^2.88.0"
}
}
MongoDB with Node and Express
Node:Engine for running JavaScript outside of a browser environment. Can work with HTTP requests.
Express:Framework to simplify working with HTTP requests.
Create a new project
$ mkdir muber
$ cd muber
$ npm init
$ code . #to open in a editor(atom, code)
to install some dependencies.. you can use SuperTest which is can be used to test HTTP endpoints.
$ sudo npm install --save nodemon mongoose express mocha
$ sudo npm install --save supertest #you can use SuperTest which is can be used to test HTTP endpoints.
$ sudo npm install --save body-parser #Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
Environment Definition
node-express-mongo-environment-variable.png
Errors
(node:27919) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
Solution: Check your mongo version
mongo --version
If you are using version >= 3.1.0 change you mongo connection file to ->
MongoClient.connect("mongodb://localhost:27017/YourDB", { useNewUrlParser: true })
or your mongoose connection file to ->
mongoose.connect("mongodb://localhost:27017/YourDB", { useNewUrlParser: true });
Ideally, it's a version 4 feature but v3.1.0 and above is supporting it too. Check out MongoDB Github for details.
Error: TypeError: User is not a constructor Solution: Node is a case-sensetive language. Check your model or object..