Upload
mongodb
View
1.812
Download
4
Embed Size (px)
Citation preview
MongoDB + Node.js
Building first app with MongoDB and Node.js
3
Agenda
MongoDB + Node.js
Driver
ODM's
MEAN Stack
Meteor
4
Ola, I'm Norberto!
Norberto Leite
Technical Evangelist
Madrid, Spain
@nleite
http://www.mongodb.com/norberto
MongoDB Node.js
INFACT
MongoDB JavaScript
8
Few reasons why
Flexible AgileWeb
Language
9
MongoDB + Javascript
• MongoDB Shell
– JS interperter
• MongoDB MapReduce
– Runs on top of V8
– Map and Reduce functions are JS functions
• Native support for Node.js
– One of the most used Drivers out there!
– https://www.npmjs.com/package/mongodb
Node.js
11
2 Foundations
Events Streams
12
2 Foundations
• Events / Event Loop
– Single Thread Applications
– No threads
– Events Emitter
– Event Queue
– Known Events
• Streams
– Read, Write, Both
– Unix Pipes
– We use it extensively!
Install
npm package
$ npm install mongodb
Compatibility
http://docs.mongodb.org/ecosystem/drivers/node-js/#compatibility
16
Compatibility w/ MongoDB
Initialize Project
package.json file
$ mkdir firstappnodejs
$ cd firstappnodejs
$ npm init
package.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"
}
package.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"
}
Install our new firstappnodejs app!
$ npm install
> [email protected] install …
…
> [email protected] install
> [email protected] node_modules/mongodb
├── [email protected] ([email protected], [email protected],
[email protected], [email protected])
└── [email protected] ([email protected], [email protected])
firstappnodejs/ $ ls
node_modules package.json
Connect
boot up MongoDB Server
$ mkdir ~/firstappdb
$ mongod --dbpath ~/firstappdb
boot up MongoDB Server
$ mkdir ~/firstappdb
$ mongod --dbpath ~/firstappdb --auth
--keyfile ~/n.pem
https://www.mongodb.com/products/mongodb-enterprise-advanced
boot up MongoDB Server
$ mkdir ~/firstappdb
$ mongod --dbpath ~/firstappdb --auth
--keyfile ~/n.pem
https://www.mongodb.com/products/mongodb-enterprise-advanced
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
Connect
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
//connection uri
var uri = "mongodb://localhost:27017/firstapp"
Connect
var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
//connection uri
var uri = "mongodb://localhost:27017/firstapp"
//connect to MongoDB
MongoClient.connect(uri, function(err, db){
assert.equal(null, err);
console.log("Connected correctly to server");
db.close();
});
Connect
29
Connection Pooling
• No traditional Pooling mechanism
– Single thread process
• Sockets to pipeline operations
• Failover
– Buffering up operations
– bufferMaxEntries
– numberOfRetries
– retryMiliSeconds
http://mongodb.github.io/node-mongodb-native/2.0/api/Db.html
CRUD
var 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);
});
}
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
var 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);
});
}
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
var 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);
});
}
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
var 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);
});
}
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
MongoClient.connect(uri, function(err, db) {
assert.equal(null, err);
console.log("Sweet! Talking to Server");
insertDocuments(db, function() {
db.close();
});
});
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
MongoClient.connect(uri, function(err, db) {
assert.equal(null, err);
console.log("Sweet! Talking to Server");
insertDocuments(db, function() {
db.close();
});
});
Insert
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#insert
var 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);
});
}
Update
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update
var 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);
});
}
Update
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update
var 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);
});
}
Update
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update
var 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);
});
}
Update
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update
MongoClient.connect(uri, function(err, db) {
assert.equal(null, err);
console.log("Ok, I can now update!");
updateDocuments(db, function() {
db.close();
});
});
Update
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#update
Remove
var 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 contaminateddata!");
cb(result);
});
}
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove
Remove
var 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 contaminateddata!");
cb(result);
});
}
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove
Remove
var 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 contaminateddata!");
cb(result);
});
}
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#remove
Remove
MongoClient.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
Find
var 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
Find
var 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
Find
var 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
Flexibility
Schema Flexibility
Different Schemas
var 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 Schemas
var 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
WriteConcern w:2
WriteConcern j:true
Different WriteConcerns
var 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.html
Different WriteConcerns
var 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.html
Read Preference
60
Read Preference
• Read from Primary (default)
ReadPreference.PRIMARY
• Read from Primary Preferably
ReadPreference.PRIMARY_PREFERRED
• Read from Secondary
ReadPreference.SECONDARY
• Read from Secondary Preferably
ReadPreference.SECONDARY_PREFERRED
• Read from Nearest Node
ReadPreference.NEAREST
http://mongodb.github.io/node-mongodb-native/2.0/api/ReadPreference.html
Read From Nearest
var 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
Read From Nearest
var 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
Read From Nearest
var 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
Aggregation
Aggregation
var 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#aggregate
Aggregation
var 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#aggregate
Aggregation
var 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#aggregate
Aggregation
var 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#aggregate
ODM's
Mongoose
71
Mongoose
• Schema Validation
• Casting
• Business Logic Wrapper
• http://mongoosejs.com/
Simple Mongoose
var mongoose = require('mongoose'), assert =require('assert')
var Schema = mongoose.Schema;
//define a schema
var userSchema = new Schema({ name: String, age:Number})
//create static members
userSchema.statics.findByName = function( name, cb){
return this.find( {"name": name}, cb);
}
…
Simple Mongoose
…
//generate a model
var User = mongoose.model('User', userSchema);
//initiate the new user, validates the given arguments
var u1 = User({name:"Many Delgado", age:14});
//just save it
u1.save(function(err){
assert.equal(null, err);
});
74
Other Projects
Project Repository
MongoSkin https://github.com/kissjs/node-mongoskin
Mongolia https://github.com/masylum/mongolia
Mongojs https://github.com/mafintosh/mongojs
MongoSmash https://github.com/bengl/mongosmash
MEAN Stack
76
MEAN Stack
• MongoDB
• Express.js
• Angular JS
• Node.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 Stack
https://www.mongodb.com/blog/post/building-
your-first-application-mongodb-creating-rest-
api-using-mean-stack-part-1
Meteor
Meteor is a complete open source platform
for building web and mobile apps in pure
JavaScript.
82
Meteor
• Responsiveness
• Reactiveness
• Multiplatform
• Unified Package System
• Hot Deploys
https://www.meteor.com/try
METEOR: Build IOS and Android Apps
that are a delight to use
http://www.mongodb.com/blog/post/meteor-
build-ios-and-android-apps-are-delight-use
Recap
85
What we talked about today…
• Node.js is a very productive language
– Our driver is highly adopted
– Updated
– Fully compatible
• CRUD Operations
– Insert, Update, Remove, Delete
• Write Concerns
– Flexible to write
• Read Preferences
– Flexible to read
• Aggregation Framework
– Analytics at your fingertips
86
Large Ecosystem
• Mongoose
• Mean Stack
• Meteor
• Many other projects
87
Where to next?
• Questions on the driver:
– https://groups.google.com/forum/#!forum/node-mongodb-native
• Issues:
– https://jira.mongodb.org/browse/NODE/?selectedTab=com.atlass
ian.jira.jira-projects-plugin:summary-panel
• Tutorial:
– http://mongodb.github.io/node-mongodb-native/2.0/
• Todays code:
– https://github.com/nleite/firstappnodejs
• Other:
– http://www.mongodb.com/norberto
http://www.mongodb.com/webinar/managing-
mission-critical-app-downtime
89
For More Information
Resource Location
Case Studies mongodb.com/customers
Presentations mongodb.com/presentations
Free Online Training education.mongodb.com
Webinars and Events mongodb.com/events
Documentation docs.mongodb.org
MongoDB Downloads mongodb.com/download
Additional Info [email protected]
Blog blog.mongodb.com
90
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.jpg
Questions?
@nleite
http://www.mongodb.com/norberto