Webinar: Building Your First App in Node.js

  • Published on
    15-Jul-2015

  • View
    118

  • Download
    2

Transcript

PowerPoint Presentation

MongoDB + Node.jsBuilding first app with MongoDB and Node.js

AgendaMongoDB + Node.jsDriver ODM'sMEAN StackMeteor#Ola, I'm Norberto!Norberto LeiteTechnical Evangelist

Madrid, Spain@nleitenorberto@mongodb.comhttp://www.mongodb.com/norberto

#MongoDB Node.js- Change this hear to a better edited one5INFACT MongoDB JavaScript- Change this hear to a better edited one7Few reasons why

FlexibleAgileWeb Language#MongoDB + JavascriptMongoDB ShellJS interperterMongoDB MapReduceRuns on top of V8Map and Reduce functions are JS functionsNative support for Node.jsOne of the most used Drivers out there!https://www.npmjs.com/package/mongodb

#Node.js2 Foundations

Events

Streams#2 FoundationsEvents / Event LoopSingle Thread ApplicationsNo threadsEvents EmitterEvent QueueKnown Events

StreamsRead, Write, BothUnix PipesWe use it extensively!#Installnpm package$ npm install mongodbBasic Driver installation for Node.js is to follow npm repository

14Compatibility

http://docs.mongodb.org/ecosystem/drivers/node-js/#compatibilityCompatibility w/ MongoDB

#Initialize Projectpackage.json file$ mkdir firstappnodejs$ cd firstappnodejs$ npm init

We should create a project folder Initialized it with NPMAdd the dependency to MongoDB lattes version the file should resemble something very similar to the shown example18package.json file$ mkdir firstappnodejs$ cd firstappnodejs$ npm init...{ "name": "firstappnodejs", "version": "0.0.1", "description": "Small demo webinar application", "main": "index.js", "scripts": { "test": "workitout" }, "repository": { "type": "git", "url": "git://github.com/nleite/firstappnodejs" }, "dependencies": { "mongodb": "~2.0" }, "keywords": [http://docs.mongodb.org/ecosystem/drivers/node-js/#compatibility "demo", "nodejs", "mongodb" ], "author": "Norberto Leite", "license": "Apache 2.0", "bugs": { "url": "https://github.com/nleite/firstappnodejs/issues" }, "homepage": "https://github.com/nleite/firstappnodejs"}We should create a project folder Initialized it with NPMAdd the dependency to MongoDB lattes version the file should resemble something very similar to the shown example19package.json file$ mkdir firstappnodejs$ cd firstappnodejs$ npm init...{ "name": "firstappnodejs", "version": "0.0.1", "description": "Small demo webinar application", "main": "index.js", "scripts": { "test": "workitout" }, "repository": { "type": "git", "url": "git://github.com/nleite/firstappnodejs" }, "dependencies": { "mongodb": "~2.0" }, "keywords": [ "demo", "nodejs", "mongodb" ], "author": "Norberto Leite", "license": "Apache 2.0", "bugs": { "url": "https://github.com/nleite/firstappnodejs/issues" }, "homepage": "https://github.com/nleite/firstappnodejs"}- But do not forget to edit the dependencies accordingly!20Install our new firstappnodejs app!$ npm install

> kerberos@0.0.10 install > bson@0.3.1 install> mongodb@2.0.28 node_modules/mongodb readable-stream@1.0.31 (isarray@0.0.1, inherits@2.0.1, string_decoder@0.10.31, core-util-is@1.0.1) mongodb-core@1.1.25 (kerberos@0.0.10, bson@0.3.1)

firstappnodejs/ $ lsnode_modules package.jsonConnectboot up MongoDB Server$ mkdir ~/firstappdb$ mongod --dbpath ~/firstappdb Raises a server listening on port 27017 by default and pointing to ~/firstappdb 23boot up MongoDB Server$ mkdir ~/firstappdb$ mongod --dbpath ~/firstappdb --auth --keyfile ~/n.pem https://www.mongodb.com/products/mongodb-enterprise-advancedDo not forget that mongodb is ready for the authentication + authorization + auditing 24boot up MongoDB Server$ mkdir ~/firstappdb$ mongod --dbpath ~/firstappdb --auth --keyfile ~/n.pem https://www.mongodb.com/products/mongodb-enterprise-advancedDon't Forget About Authentication in ProductionDo not forget that mongodb is ready for the authentication + authorization + auditing 25var MongoClient = require('mongodb').MongoClient, assert = require('assert');

Connectvar MongoClient = require('mongodb').MongoClient, assert = require('assert');

//connection urivar uri = "mongodb://localhost:27017/firstapp"

Connect27var MongoClient = require('mongodb').MongoClient, assert = require('assert');

//connection urivar uri = "mongodb://localhost:27017/firstapp"

//connect to MongoDBMongoClient.connect(uri, function(err, db){ assert.equal(null, err); console.log("Connected correctly to server"); db.close();});

ConnectConnection PoolingNo traditional Pooling mechanismSingle thread processSockets to pipeline operationsFailover Buffering up operations bufferMaxEntriesnumberOfRetriesretryMiliSecondshttp://mongodb.github.io/node-mongodb-native/2.0/api/Db.html#Pooling: there are no traditional concept of connection pools since this is a single threaded process. We use sockets to pupeline the commands to MongoDB.Failover consists on buffering up the commands till the servers are availableThese can be controlled by bufferMaxEntries, numberOfRetries and retryMiliSeconds

29CRUDvar insertDocuments = function(db, cb){ //we don't need to explicitly create a collection var collection = db.collection('myCollection'); collection.insertMany([ {"mongodb": "is just awesome"}, {"nodejs": "so awesome"} ], function(err, result){ assert.equal(null, err); //inserted 2 documents assert.equal(2, result.insertedCount); //invoke callback cb(result); });}Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertvar insertDocuments = function(db, cb){ //we don't need to explicitly create a collection var collection = db.collection('myCollection'); collection.insertMany([ {"mongodb": "is just awesome"}, {"nodejs": "so awesome"} ], function(err, result){ assert.equal(null, err); //inserted 2 documents assert.equal(2, result.insertedCount); //invoke callback cb(result); });}Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertvar insertDocuments = function(db, cb){ //we don't need to explicitly create a collection var collection = db.collection('myCollection'); collection.insertMany([ {"mongodb": "is just awesome"}, {"nodejs": "so awesome"} ], function(err, result){ assert.equal(null, err); //inserted 2 documents assert.equal(2, result.insertedCount); //invoke callback cb(result); });}Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertvar insertDocuments = function(db, cb){ //we don't need to explicitly create a collection var collection = db.collection('myCollection'); collection.insertMany([ {"mongodb": "is just awesome"}, {"nodejs": "so awesome"} ], function(err, result){ assert.equal(null, err); //inserted 2 documents assert.equal(2, result.insertedCount); //invoke callback cb(result); });}Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertMongoClient.connect(uri, function(err, db) { assert.equal(null, err); console.log("Sweet! Talking to Server");

insertDocuments(db, function() { db.close(); });});

Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertMongoClient.connect(uri, function(err, db) { assert.equal(null, err); console.log("Sweet! Talking to Server");

insertDocuments(db, function() { db.close(); });});

Inserthttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insertvar updateDocument = function(db, cb){ var collection = db.collection("myCollection");

collection.updateOne( {"mongodb": "is just awesome"}, {$set: {"users": ["nleite"]}}, function( err, result){ assert.equal(null, err); assert.equal(1, result.modifiedCount);

console.log("Cool, just updated");

cb(result); });}

Updatehttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#updatevar updateDocument = function(db, cb){ var collection = db.collection("myCollection");

collection.updateOne( {"mongodb": "is just awesome"}, {$set: {"users": ["nleite"]}}, function( err, result){ assert.equal(null, err); assert.equal(1, result.modifiedCount);

console.log("Cool, just updated");

cb(result); });}

Updatehttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update- Define the query to match the wanted documents38var updateDocument = function(db, cb){ var collection = db.collection("myCollection");

collection.updateOne( {"mongodb": "is just awesome"}, {$set: {"users": ["nleite"]}}, function( err, result){ assert.equal(null, err); assert.equal(1, result.modifiedCount);

console.log("Cool, just updated");

cb(result); });}

Updatehttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update$set operator that will perform the change In this case will produce the set of new array field39var updateDocument = function(db, cb){ var collection = db.collection("myCollection");

collection.updateOne( {"mongodb": "is just awesome"}, {$set: {"users": ["nleite"]}}, function( err, result){ assert.equal(null, err); assert.equal(1, result.modifiedCount);

console.log("Cool, just updated");

cb(result); });}

Updatehttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#updateVerify that the operation occurred without errors and matches the expected end resultIn this case 1 updated document 40MongoClient.connect(uri, function(err, db) { assert.equal(null, err); console.log("Ok, I can now update!");

updateDocuments(db, function() { db.close(); });});

Updatehttp://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#updateRemovevar removeDocument = function(db, cb){ var collection = db.collection("myCollection"); collection.deleteOne( {"users": "nleite"}, function( err, result){ assert.equal(null, err); assert.equal(1, result.deletedCount); console.log("purged the @nleite contaminated data!"); cb(result); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#removeRemovevar removeDocument = function(db, cb){ var collection = db.collection("myCollection"); collection.deleteOne( {"users": "nleite"}, function( err, result){ assert.equal(null, err); assert.equal(1, result.deletedCount); console.log("purged the @nleite contaminated data!"); cb(result); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove- Performs a multikey query operation43Removevar removeDocument = function(db, cb){ var collection = db.collection("myCollection"); collection.deleteOne( {"users": "nleite"}, function( err, result){ assert.equal(null, err); assert.equal(1, result.deletedCount); console.log("purged the @nleite contaminated data!"); cb(result); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#removeRemoveMongoClient.connect(uri, function(err, db) { assert.equal(null, err); console.log("Ok, I can now delete!");

removeDocuments(db, function() { db.close(); });});

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove

Findvar findAllDocuments = function(db, cb){ var collection = db.collection('myDocuments'); //or collection.find() collection.find({}).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("Gotcha! found "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findFindvar findAllDocuments = function(db, cb){ var collection = db.collection('myDocuments'); //or collection.find() collection.find({}).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("Gotcha! found "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findFindvar findAllDocuments = function(db, cb){ var collection = db.collection('myDocuments'); //or collection.find() collection.find({}).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("Gotcha! found "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#find- The only variation on this case is that we are not going to handle the results object but the cursor returned by the query method48FlexibilitySchema Flexibility

Different Schemasvar insertDifferentShapes = function(db, cb){

var doc1 = {"name": "Norberto", "talks": [ {"nodejs":10}, {"java":15}, "python":11]}; var doc2 = {"name": "Bryan", "webinars": 30};

var coll = db.collection("content") coll.insertMany( [doc1, doc2], function(err, result){ assert.equal(err, null); assert.equal(2, result.insertedCount);

console.log("Sweet, inserted "+ result.insertedCount); cb(result); });}http://docs.mongodb.org/manual/data-modeling/Different Schemasvar insertDifferentShapes = function(db, cb){

var doc1 = {"name": "Norberto", "talks": [ {"nodejs":10}, {"java":15}, "python":11]}; var doc2 = {"name": "Bryan", "webinars": 30};

var coll = db.collection("content") coll.insertMany( [doc1, doc2], function(err, result){ assert.equal(err, null); assert.equal(2, result.insertedCount);

console.log("Sweet, inserted "+ result.insertedCount); cb(result); });}http://docs.mongodb.org/manual/data-modeling/WriteConcerns

WriteConcern w:1

Change this slid54WriteConcern w:2

WriteConcern j:true

Different WriteConcernsvar insertSuperImportant = function(db, cb){

var customer = {"name": "Manny Delgado", "age": 14}; var coll = db.collection("customers");

var writeConcern = {"w": "majority"};

col.insertOne( customer, writeConcern, function(err, result){ assert.equal(err, null); assert.equal(1, result.insertedCount);

console.log("Inserted super important record"); cb(result); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/WriteConcernError.htmlDifferent WriteConcernsvar insertSuperImportant = function(db, cb){

var customer = {"name": "Manny Delgado", "age": 14}; var coll = db.collection("customers");

var writeConcern = {"w": "majority"};

col.insertOne( customer, writeConcern, function(err, result){ assert.equal(err, null); assert.equal(1, result.insertedCount);

console.log("Inserted super important record"); cb(result); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/WriteConcernError.htmlRead Preference

Read PreferenceRead from Primary (default)ReadPreference.PRIMARYRead from Primary PreferablyReadPreference.PRIMARY_PREFERREDRead from SecondaryReadPreference.SECONDARYRead from Secondary Preferably ReadPreference.SECONDARY_PREFERREDRead from Nearest NodeReadPreference.NEARESThttp://mongodb.github.io/node-mongodb-native/2.0/api/ReadPreference.html#- Also mention the fact that we can specify the way we want to read from using replica tags60Read From Nearestvar readNearestWaterMelonColor = function(db, cb){ var rp = ReadPreference.NEAREST;

var coll = db.collection("products", {ReadPreference:rp});

var query = {"color": "water melon green"}; collection.find(query).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("So many products: "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/ReadPreference.htmlRead From Nearestvar readNearestWaterMelonColor = function(db, cb){ var rp = ReadPreference.NEAREST;

var coll = db.collection("products", {ReadPreference:rp});

var query = {"color": "water melon green"}; collection.find(query).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("So many products: "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/ReadPreference.html- Define the Nearest read preference 62Read From Nearestvar readNearestWaterMelonColor = function(db, cb){ var rp = ReadPreference.NEAREST;

var coll = db.collection("products", {readPreference:rp});

var query = {"color": "water melon green"}; collection.find(query).toArray(function(err, docs){ assert.equal(err, null); assert.equal(1, docs.length);

console.log("So many products: "+ docs.length); console.dir(docs); cb(docs); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/ReadPreference.htmlSet it at collection levelWe can set this at connection, db, collection and instruction level63Aggregation

Aggregationvar aggregateAvgAgeGender = function( db, cb){ //{age:XX, name:"user name", gender: "M/F"} var pipeline = [ {$group: { "_id": "$gender", avg_age: {$avg: "$age"}}}, ];

var coll = db.collection("users"); var cursor = coll.aggregate(pipeline); cursor.forEach( function(x){ console.log("Gender " + x._id + " age average " + x.avg_age) }, function(x) { cb(cursor); });}http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#aggregateAggregationvar aggregateAvgAgeGender = function( db, cb){ //{age:XX, name:"user name", gender: "M/F"} var pipeline = [ {$group: { "_id": "$gender", avg_age: {$avg: "$age"}}}, ];

var coll = db.collection("users"); var cursor = coll.aggregate(pipeline); cursor.forEach( function(x){ console.log("Gender " + x._id + " age average " + x.avg_age) }, function(x) { cb(cursor); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#aggregateAggregationvar aggregateAvgAgeGender = function( db, cb){ //{age:XX, name:"user name", gender: "M/F"} var pipeline = [ {$group: { "_id": "$gender", avg_age: {$avg: "$age"}}}, ];

var coll = db.collection("users"); var cursor = coll.aggregate(pipeline); cursor.forEach( function(x){ console.log("Gender " + x._id + " age average " + x.avg_age) }, function(x) { cb(cursor); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#aggregateAggregationvar aggregateAvgAgeGender = function( db, cb){ //{age:XX, name:"user name", gender: "M/F"} var pipeline = [ {$match:{"age": $gt: 18}}, {$group: { "_id": "$gender", avg_age: {$avg: "$age"}}}, {$project:{"ID": "$_id", "average": "$avg_age" }} ];

var cursor = coll.aggregate(pipeline); var coll = db.collection("users"); cursor.forEach( function(x){ console.log("Gender " + x._id + " age average " + x.avg_age) }, function(x) { cb(cursor); });}

http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#aggregatedon't forget this is a pipeline of operations We can build it in a programmatically shape to adjust to what we need to extract68ODM'sMongoose

MongooseSchema Validation

Casting

Business Logic Wrapper

http://mongoosejs.com/#71Simple Mongoosevar mongoose = require('mongoose'), assert = require('assert')var Schema = mongoose.Schema;//define a schemavar userSchema = new Schema({ name: String, age: Number})//create static membersuserSchema.statics.findByName = function( name, cb){ return this.find( {"name": name}, cb);}

Simple Mongoose//generate a modelvar User = mongoose.model('User', userSchema);//initiate the new user, validates the given argumentsvar u1 = User({name:"Many Delgado", age:14});//just save itu1.save(function(err){ assert.equal(null, err);});

Other ProjectsProjectRepositoryMongoSkinhttps://github.com/kissjs/node-mongoskinMongoliahttps://github.com/masylum/mongoliaMongojshttps://github.com/mafintosh/mongojsMongoSmashhttps://github.com/bengl/mongosmash#Mongojs simulates the mongoshell from nodejsMongoskin layer for mongo-native nodejs driverMongolia lightweight ODM

74MEAN StackMEAN StackMongoDBExpress.jsAngular JSNode.js

#Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop

Building your first app with MongoDB: Creating a REST API using the MEAN Stackhttps://www.mongodb.com/blog/post/building-your-first-application-mongodb-creating-rest-api-using-mean-stack-part-1MeteorMeteor is a complete open source platform for building web and mobile apps in pure JavaScript.

MeteorResponsivenessReactiveness MultiplatformUnified Package SystemHot Deploys

https://www.meteor.com/try#METEOR: Build IOS and Android Apps that are a delight to usehttp://www.mongodb.com/blog/post/meteor-build-ios-and-android-apps-are-delight-useRecapWhat we talked about todayNode.js is a very productive languageOur driver is highly adoptedUpdatedFully compatible CRUD OperationsInsert, Update, Remove, DeleteWrite ConcernsFlexible to write Read PreferencesFlexible to readAggregation Framework Analytics at your fingertips#Large EcosystemMongooseMean Stack MeteorMany other projects#Where to next?Questions on the driver:https://groups.google.com/forum/#!forum/node-mongodb-nativeIssues:https://jira.mongodb.org/browse/NODE/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panelTutorial:http://mongodb.github.io/node-mongodb-native/2.0/Todays code:https://github.com/nleite/firstappnodejsOther:http://www.mongodb.com/norberto#http://www.mongodb.com/webinar/managing-mission-critical-app-downtime

For More InformationResourceLocationCase Studiesmongodb.com/customersPresentationsmongodb.com/presentationsFree Online Trainingeducation.mongodb.comWebinars and Eventsmongodb.com/eventsDocumentationdocs.mongodb.orgMongoDB Downloadsmongodb.com/downloadAdditional Infoinfo@mongodb.comBlog blog.mongodb.com#

Register now: mongodbworld.com

Use Code NorbertoLeite for additional 25% Off*Come as a group of 3 or more Save another 25%#

http://cl.jroo.me/z3/v/D/C/e/a.baa-Too-many-bicycles-on-the-van.jpgQuestions?@nleitenorberto@mongodb.comhttp://www.mongodb.com/norberto

92