SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
by 桂林
All languages used
Browser script: javaS c r ip t

Server script: javaS c r ip t

Database script: javaS c r ip t
All languages used
Browser script: javaS c r ip t

Server script: javaS c r ip t

Database script: javaS c r ip t
Overview of MongoDB

Patterns of mongoskin
Why MongoDB




Agile and Scalable
Overview of MongoDB
MySQL
posts
 id



comments
 id

 post_id



tags
 id

 name



posts_tags
 post_id

 tag_id
Overview of MongoDB
Database >> Database

Table >> Collection

Row >> Document
Overview of MongoDB
M on g oD B
{
    _id: ObjectId(),
    title: 'node and mongodb',
    slug: 'node-and-mongodb',
    body: '...',
    published: true,
    created: new Date('09/01/2011'),
    updated: new Date('09/16/2011'),
    comments: [
      {
        author: 'bob',
        email: 'bob@bob.me',
        body: '...',
        created: new Date('09/17/2011')
      }
    ],
    tags: ['MongoDB', 'database']
}
Overview of MongoDB
Get c ollec t ion
MongoDB shell
posts = db.posts

NodeJS
var mongodb = require('mongodb');
var db = new Db('test', new Server(host, port, {}),
{native_parser:true});
db.open(function(err, db){
    db.collection('posts', function(err, posts){
      // use posts collection here
    });
});
Overview of MongoDB
I n ser t
MongoDB shell
var doc = {title: 'test posts', ...};
posts.insert(doc);

NodeJS
posts.insert(doc, function(err, reply){
    // error or done
});
Overview of MongoDB
Q u er y
MongoDB shell
posts.find({"comments.author", "bob"})

NodeJS
posts.find({"comments.author", "bob"}, function(err, cursor){
    cursor.toArray(function(err, docs){
        // found docs here
    });
});
Overview of MongoDB
Q u er y op er at or
{<field>:{<operator>:<value>}}

db.things.find({j:{$in: [2,4,6]}});

 $gt, $lt, $gte, $lte

 $all, $exists

 $mod, $ne

 $in, $nin

 $nor, $or, $and

 $size, $type, …
Overview of MongoDB
Up d at e
MongoDB shell
posts.update({_id: doc.id}, {$inc: {votes: 1}})

NodeJS
posts.update({_id: doc.id}, {$inc: {votes: 1}}, function(err, count){
});
Overview of MongoDB
M od if ier op er at ion s
 $set – set a particular value

 $unset – delete a particular field (v1.3+)

 $inc – increment a particular value by a certain amount

 $push – append a value to an array

 $pushAll – append several values to an array

 $pull – remove a value(s) from an existing array

 $pullAll – remove several value(s) from an existing array

 $bit – bitwise operations
Overview of MongoDB
R em ove
MongoDB shell
posts.remove({author: 'bob'})

NodeJS
posts.remove({author: 'bob'}, function(err, reply){})
Overview of MongoDB
I n d ex
MongoDB shell
posts.ensureIndex({author:1})
posts.ensureIndex({slug: 1 }, {unique: true});
db.things.ensureIndex(
    {firstname: 1, lastname: 1},
    {unique: true, background:true});

NodeJS
posts.ensureIndex({author:1}, function(err, reply){})
posts.ensureIndex({slug: 1 }, {unique: true}, function(err, reply){});
db.things.ensureIndex(
    {firstname: 1, lastname: 1},
    {unique: true, background:true}, function(err, reply){});
Overview of MongoDB
Geosp at ial
{   loc   :   [   50 , 30 ] } //SUGGESTED OPTION
{   loc   :   {   x : 50 , y : 30 } }
{   loc   :   {   foo : 50 , y : 30 } }
{   loc   :   {   lon : 40.739037, lat: 73.992964 } }

db.places.ensureIndex( { loc : "2d" } )
db.places.find( { loc : { $near : [50,50] , $maxDistance : 5 } } )

box = [[40.73083, -73.99756], [40.741404, -73.988135]]
db.places.find({"loc" : {"$within" : {"$box" : box}}})

center = [50, 50]
radius = 10
db.places.find({"loc" : {"$within" : {"$center" : [center, radius]}}})
Overview of MongoDB
O p t im izat ion
 Don’t create index for every field

 Be careful about single-key indexes with low selectivity.

 Only one index could be used per query.

 Use compound-key index.
 db.places.ensureIndex( { location : “2d” , category : 1 } );
 db.places.find( { location : { $near : [50,50] }, category : ‘coffee’ } );

 Use hint. Use explain. Use the profiler.

 Pay attention to the read/write ratio of your application.
See docs for more information
Overview of MongoDB
Ag g r eg at ion
 posts.count( {author: 'bob'} )
 posts.distinct("author")

SQL group
 select a,b,sum(c) csum from coll where active=1 group by a,b

MongoDB group
 db.coll.group(
        {key: { a:true, b:true },
         cond: { active:1 },
         reduce: function(obj, out) { out.csum += obj.c; },
         initial: { csum: 0 }
       });
Overview of MongoDB
M ap R ed u c e
map = function() {
    for (var i in this.tags) {
        emit(this.tags[i], 1);
    }
}

reduce = function(key, values) {
    var count = 0;
    for (var i in values) {
        count += current[i];
    }
    return count;
}

// 1.8+ must set out collection
db.posts.mapReduce(map, reduce, {out: 'tags_count'})
Overview of MongoDB
M ap R ed u c e
> db.tags_count.find()
{"_id" : "MongoDB", "value" : 4}
{"_id" : "Map/Reduce", "value" : 2}
{"_id" : "Recipe", "value" : 7}
{"_id" : "Group", "value" : 1}
Overview of MongoDB
Gr id F S
Upload image
var gridStore = new GridStore(db, filename, "w");
gridStore.open(function(err, gridStore) {
  gridStore.write(imageData, function(err, gridStore) {
    gridStore.close(function(err, result) {
      console.log(result._id);
      users.update({_id: userId}, {$set: {avatarId: result._id}});
    });
  });
});

HTML
<img src="http://asset.url/gridfs/{{ user.avatarId }}" />

 Use nginx-gridfs
Overview of MongoDB
R ep lic at ion and S h ar d in g
Nice
Nice ,but node
Nest ed c allb ac k s, an d n ot D R Y ?
var database = new mongo.Db('testdb', new mongo.Server('localhost',
27017));
database.open(function(err, db) {
    if(err) return handle(err);
    db.collection('user', function(err, collection) {
        if(err) return handle(err);
        collection.find({}, function(err, cursor) {
            if(err) return handle(err);
            cursor.toArray(function(err, users) {
                if(err) return handle(err);
                doSomething(users);
            });
        });
    });
});
How t o exp or t c ollec t ion
var database = new mongo.Db('testdb', new mongo.Server('localhost',
27017));
database.open(function(err, db){
    db.collection('posts', function(err, posts) {
      // can't export here?
    });
});
exports.posts = ?
How t o sh ar e c ollec t ion ob jec t
controllers/user.js
var database = new mongo.Db('testdb', new mongo.Server('localhost',
27017));
//...
database.open(function(err, db){
    db.collection('user', function(err, userColl){

            userColl.find({}, function(err, cursor){
                if(err) return handle(err);
                cursor.toArray(function(err, users){
                    res.render('/user.html', {users: users});
                })
            });

      });
});
How t o sh ar e c ollec t ion ob jec t
controllers/book.js
var database = new mongo.Db('testdb', new mongo.Server('localhost',
27017));
//...
database.open(function(err, db){
    db.collection('user', function(err, userColl){
        userColl.findOne({_id: book.author_id}, function(err, author){
            res.render('/book.html', {book: book, author: author});
        });
    });
});
Redsign the API
How ab ou t t h is
config.js
exports.db = mongo.db('mongo://localhost:27017/testdb')
An d t h is
controllers/user.js
var db = require('../config').db;
db.collection('user').find({}).toArray(function(err, users){
    if(err) return handle(err);
    res.render('/user.html', {users: users});
});
An d t h is
controllers/book.js
var db = require('../config').db;
db.collection('user').findOne({_id, book.author_id}, function(err,
author){
    if(err) return handle(err);
    res.render('/book.html', {book: book, author: author});
});
It’s MongoSkin
Patterns of mongoskin
var mongoskin = require('mongoskin');

var db = mongoskin.db('mongo://localhost:27017/testdb');

db.bind('users');
db.bind('books');

db.users.find({}).limit(10).sort({name:-1}).toArray(function(err,
users){
});

db.books.update({_id: bookId}, {$inc: {votes: 1}}, function(err,
reply){
});
Patterns of mongoskin
Pr oxy all m et h od s
node-mongoskin
var skindb = mongoskin.db('mongo://localhost:27017/testdb')
function callback(err, reply){}
skindb.addUser('foo', 'bar', callback);

node-mongodb-native
var db = new mongodb.Db('testdb',
    new mongodb.Server('localhost', 27017));

function callback(err, reply){}
db.open(function(err, db){
    if(err) return callback(err);
    db.addUser('foo', 'bar', callback);
});
Patterns of mongoskin
SkinClass hold all parameters to open it
var SkinDb = exports.SkinDb = function(db, username, password) {
  this.db = db;
  this.username = username;
  this.password = password;
  this.state = STATE_CLOSE;
  this.emitter = new events.EventEmitter();
  this._collections = {};
};
Patterns of mongoskin
Proxy all methods inside open
for (var name in Db.prototype) {
  SkinDb.prototype[name] = function() {
    var args = Array.prototype.slice.call(arguments);
    this.open(function(err, db) {
      if (err) {
        return args[args.length - 1](err);//callback(err)
      } else {
        return Db.prototype[name].apply(db, args);
      }
    });
  };
}
Patterns of mongoskin
Open only on c e (pseudo-code)
SkinDb.prototype.open = function(fn) {
  switch (this.state) {

  case STATE_OPEN:
    return fn(null, this.db);

  case STATE_OPENNING:
    // if call 'open' method multi times before opened
    return this.emitter.addListener('open', fn);

  case STATE_CLOSE:
    this.state = STATE_OPENNING;
    var that = this;
    this.db.open(function(err, db){
        that.db = db;
        fn(err, db);
        that.state = STATE_OPEN;
        that.emitter.emit('open', err, db);
    });
 }
}
 };
      Patterns of mongoskin
R et u r n s S k in Collec t ion
 SkinDb.prototype.collection = function(name) {
   var collection = this._collections[name];
   if (!collection) {
     this._collections[name] = collection = new SkinCollection(this,
 name);
   }
   return collection;
 };
Patterns of mongoskin
S k in Collec t ion
 var SkinCollection = exports.SkinCollection = function(skinDb,
 collectionName) {
   this.skinDb = skinDb;
   this.collectionName = collectionName;
   this.collection;
   this.state = STATE_CLOSE;
   this.internalHint;
   var that = this;
   this.__defineGetter__('hint', function() { return this.internalHint;
 });
   this.__defineSetter__('hint', function(value) {
       this.internalHint = value;
       this.open(function(err, collection) {
         collection.hint = value;
         that.internalHint = collection.hint;
       });
   });

     this.emitter = new events.EventEmitter();
 }
}


    Patterns of mongoskin
Pr oxy all m et h od s in sid e S k in Collec t ion . op en
for (var name in Collection.prototype) {
  SkinCollection.prototype[name] = function() {
    var args = Array.prototype.slice.call(arguments);
    this.open(function(err, collection) {
      if (err) {
        args[args.length - 1](err);// callback(err)
      } else {
        Collection.prototype[name].apply(collection, args);
      }
    });
  };
}
Patterns of mongoskin
S k in Collec t ion . op en
 SkinCollection.prototype.open = function(callback) {
   //...
   var that = this;
   this.skinDb.open(function(err, db){
       db.collection(that.collectionName, function(err, collection){
         this.nativeCollection = collection;
         callback(err, collection);
       }
   });
 }
Patterns of mongoskin
R et u r n s S k in Cu r sor if n o c allb ac k
 SkinCollection.prototype.find = function() {
   var args = Array.prototype.slice.call(arguments);
   if (args.length > 0 && typeof(args[args.length - 1]) === 'function')
 {
     this._find.apply(this, args);
   }else {
     return new SkinCursor(null, this, args);
   }
 };

An d so d o w it h S k in Cu r sor
Patterns of mongoskin
Pat t er n s of m on g osk in
 SkinClass contains all parameters to get NativeObject

 Proxy all method inside callback of op en ( )

 Make open() method cache result

 Return SkinClass object to chain execution
Reference
MongoDB The Definitive Guide

MongoDB Docs http://www.mongodb.org/display/DOCS/Home

MongoDB Cookbook http://cookbook.mongodb.org/

Node mongodb https://github.com/christkv/node-mongodb-native

Mongoskin https://github.com/guileen/node-mongoskin
Thank you
   桂糊涂@weibo

 guileen@gmail.com

Weitere ähnliche Inhalte

Was ist angesagt?

mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introductionTse-Ching Ho
 
MongoDB Aggregation
MongoDB Aggregation MongoDB Aggregation
MongoDB Aggregation Amit Ghosh
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Tsuyoshi Yamamoto
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineJason Terpko
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)MongoSF
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Nodejs mongoose
Nodejs mongooseNodejs mongoose
Nodejs mongooseFin Chen
 
Declarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceDeclarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceAlexander Gladysh
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery PresentationSony Jain
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to PigChris Wilkes
 
jQuery Datatables With MongDb
jQuery Datatables With MongDbjQuery Datatables With MongDb
jQuery Datatables With MongDbsliimohara
 

Was ist angesagt? (20)

mongodb-introduction
mongodb-introductionmongodb-introduction
mongodb-introduction
 
MongoDB Aggregation
MongoDB Aggregation MongoDB Aggregation
MongoDB Aggregation
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察
 
Academy PRO: ES2015
Academy PRO: ES2015Academy PRO: ES2015
Academy PRO: ES2015
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation Pipeline
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Php 101: PDO
Php 101: PDOPhp 101: PDO
Php 101: PDO
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Coffee script
Coffee scriptCoffee script
Coffee script
 
Nodejs mongoose
Nodejs mongooseNodejs mongoose
Nodejs mongoose
 
Declarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing ExperienceDeclarative Internal DSLs in Lua: A Game Changing Experience
Declarative Internal DSLs in Lua: A Game Changing Experience
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
 
jQuery Datatables With MongDb
jQuery Datatables With MongDbjQuery Datatables With MongDb
jQuery Datatables With MongDb
 
はじめてのGroovy
はじめてのGroovyはじめてのGroovy
はじめてのGroovy
 

Ähnlich wie Mongoskin - Guilin

Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBUwe Printz
 
Webinar: Applikationsentwicklung mit MongoDB : Teil 5: Reporting & Aggregation
Webinar: Applikationsentwicklung mit MongoDB: Teil 5: Reporting & AggregationWebinar: Applikationsentwicklung mit MongoDB: Teil 5: Reporting & Aggregation
Webinar: Applikationsentwicklung mit MongoDB : Teil 5: Reporting & AggregationMongoDB
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation FrameworkCaserta
 
Composition in JavaScript
Composition in JavaScriptComposition in JavaScript
Composition in JavaScriptJosh Mock
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Andrii Lashchenko
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analyticsMongoDB
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL SpartakiadeJohannes Hoppe
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora 3camp
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptIngvar Stepanyan
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 

Ähnlich wie Mongoskin - Guilin (20)

Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Map/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDBMap/Confused? A practical approach to Map/Reduce with MongoDB
Map/Confused? A practical approach to Map/Reduce with MongoDB
 
Webinar: Applikationsentwicklung mit MongoDB : Teil 5: Reporting & Aggregation
Webinar: Applikationsentwicklung mit MongoDB: Teil 5: Reporting & AggregationWebinar: Applikationsentwicklung mit MongoDB: Teil 5: Reporting & Aggregation
Webinar: Applikationsentwicklung mit MongoDB : Teil 5: Reporting & Aggregation
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Composition in JavaScript
Composition in JavaScriptComposition in JavaScript
Composition in JavaScript
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Latinoware
LatinowareLatinoware
Latinoware
 
1403 app dev series - session 5 - analytics
1403   app dev series - session 5 - analytics1403   app dev series - session 5 - analytics
1403 app dev series - session 5 - analytics
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade2013-03-23 - NoSQL Spartakiade
2013-03-23 - NoSQL Spartakiade
 
MongoDB dla administratora
MongoDB dla administratora MongoDB dla administratora
MongoDB dla administratora
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
dojo.Patterns
dojo.Patternsdojo.Patterns
dojo.Patterns
 
Go react codelab
Go react codelabGo react codelab
Go react codelab
 
Mongo db dla administratora
Mongo db dla administratoraMongo db dla administratora
Mongo db dla administratora
 
Mongo DB 102
Mongo DB 102Mongo DB 102
Mongo DB 102
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 

Mehr von Jackson Tian

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版Jackson Tian
 
D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践Jackson Tian
 
Mobile webapp&v5 html5_min
Mobile webapp&v5 html5_minMobile webapp&v5 html5_min
Mobile webapp&v5 html5_minJackson Tian
 
Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Jackson Tian
 
EventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianEventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianJackson Tian
 
MobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designMobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designJackson Tian
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型Jackson Tian
 
Why Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiWhy Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiJackson Tian
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiJackson Tian
 
Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiJackson Tian
 
Browser vs. Node.js Jackson Tian Shanghai
Browser vs. Node.js   Jackson Tian ShanghaiBrowser vs. Node.js   Jackson Tian Shanghai
Browser vs. Node.js Jackson Tian ShanghaiJackson Tian
 

Mehr von Jackson Tian (12)

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版
 
D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践D2_Node在淘宝的应用实践
D2_Node在淘宝的应用实践
 
(C)NodeJS
(C)NodeJS(C)NodeJS
(C)NodeJS
 
Mobile webapp&v5 html5_min
Mobile webapp&v5 html5_minMobile webapp&v5 html5_min
Mobile webapp&v5 html5_min
 
Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成Nodejs异步原理和缺陷 - 赵成
Nodejs异步原理和缺陷 - 赵成
 
EventProxy introduction - JacksonTian
EventProxy introduction - JacksonTianEventProxy introduction - JacksonTian
EventProxy introduction - JacksonTian
 
MobileWebAppFramework_V5_design
MobileWebAppFramework_V5_designMobileWebAppFramework_V5_design
MobileWebAppFramework_V5_design
 
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
从无阻塞并行脚本加载(Lab.js)到浏览器消息模型
 
Why Nodejs Guilin Shanghai
Why Nodejs Guilin ShanghaiWhy Nodejs Guilin Shanghai
Why Nodejs Guilin Shanghai
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 Shanghai
 
Ruby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay ShanghaiRuby vs Node ShiningRay Shanghai
Ruby vs Node ShiningRay Shanghai
 
Browser vs. Node.js Jackson Tian Shanghai
Browser vs. Node.js   Jackson Tian ShanghaiBrowser vs. Node.js   Jackson Tian Shanghai
Browser vs. Node.js Jackson Tian Shanghai
 

Kürzlich hochgeladen

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Kürzlich hochgeladen (20)

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Mongoskin - Guilin

  • 2. All languages used Browser script: javaS c r ip t Server script: javaS c r ip t Database script: javaS c r ip t
  • 3. All languages used Browser script: javaS c r ip t Server script: javaS c r ip t Database script: javaS c r ip t
  • 6. Overview of MongoDB MySQL posts id comments id post_id tags id name posts_tags post_id tag_id
  • 7. Overview of MongoDB Database >> Database Table >> Collection Row >> Document
  • 8. Overview of MongoDB M on g oD B { _id: ObjectId(), title: 'node and mongodb', slug: 'node-and-mongodb', body: '...', published: true, created: new Date('09/01/2011'), updated: new Date('09/16/2011'), comments: [ { author: 'bob', email: 'bob@bob.me', body: '...', created: new Date('09/17/2011') } ], tags: ['MongoDB', 'database'] }
  • 9. Overview of MongoDB Get c ollec t ion MongoDB shell posts = db.posts NodeJS var mongodb = require('mongodb'); var db = new Db('test', new Server(host, port, {}), {native_parser:true}); db.open(function(err, db){ db.collection('posts', function(err, posts){ // use posts collection here }); });
  • 10. Overview of MongoDB I n ser t MongoDB shell var doc = {title: 'test posts', ...}; posts.insert(doc); NodeJS posts.insert(doc, function(err, reply){ // error or done });
  • 11. Overview of MongoDB Q u er y MongoDB shell posts.find({"comments.author", "bob"}) NodeJS posts.find({"comments.author", "bob"}, function(err, cursor){ cursor.toArray(function(err, docs){ // found docs here }); });
  • 12. Overview of MongoDB Q u er y op er at or {<field>:{<operator>:<value>}} db.things.find({j:{$in: [2,4,6]}}); $gt, $lt, $gte, $lte $all, $exists $mod, $ne $in, $nin $nor, $or, $and $size, $type, …
  • 13. Overview of MongoDB Up d at e MongoDB shell posts.update({_id: doc.id}, {$inc: {votes: 1}}) NodeJS posts.update({_id: doc.id}, {$inc: {votes: 1}}, function(err, count){ });
  • 14. Overview of MongoDB M od if ier op er at ion s $set – set a particular value $unset – delete a particular field (v1.3+) $inc – increment a particular value by a certain amount $push – append a value to an array $pushAll – append several values to an array $pull – remove a value(s) from an existing array $pullAll – remove several value(s) from an existing array $bit – bitwise operations
  • 15. Overview of MongoDB R em ove MongoDB shell posts.remove({author: 'bob'}) NodeJS posts.remove({author: 'bob'}, function(err, reply){})
  • 16. Overview of MongoDB I n d ex MongoDB shell posts.ensureIndex({author:1}) posts.ensureIndex({slug: 1 }, {unique: true}); db.things.ensureIndex( {firstname: 1, lastname: 1}, {unique: true, background:true}); NodeJS posts.ensureIndex({author:1}, function(err, reply){}) posts.ensureIndex({slug: 1 }, {unique: true}, function(err, reply){}); db.things.ensureIndex( {firstname: 1, lastname: 1}, {unique: true, background:true}, function(err, reply){});
  • 17. Overview of MongoDB Geosp at ial { loc : [ 50 , 30 ] } //SUGGESTED OPTION { loc : { x : 50 , y : 30 } } { loc : { foo : 50 , y : 30 } } { loc : { lon : 40.739037, lat: 73.992964 } } db.places.ensureIndex( { loc : "2d" } ) db.places.find( { loc : { $near : [50,50] , $maxDistance : 5 } } ) box = [[40.73083, -73.99756], [40.741404, -73.988135]] db.places.find({"loc" : {"$within" : {"$box" : box}}}) center = [50, 50] radius = 10 db.places.find({"loc" : {"$within" : {"$center" : [center, radius]}}})
  • 18. Overview of MongoDB O p t im izat ion Don’t create index for every field Be careful about single-key indexes with low selectivity. Only one index could be used per query. Use compound-key index. db.places.ensureIndex( { location : “2d” , category : 1 } ); db.places.find( { location : { $near : [50,50] }, category : ‘coffee’ } ); Use hint. Use explain. Use the profiler. Pay attention to the read/write ratio of your application. See docs for more information
  • 19. Overview of MongoDB Ag g r eg at ion posts.count( {author: 'bob'} ) posts.distinct("author") SQL group select a,b,sum(c) csum from coll where active=1 group by a,b MongoDB group db.coll.group( {key: { a:true, b:true }, cond: { active:1 }, reduce: function(obj, out) { out.csum += obj.c; }, initial: { csum: 0 } });
  • 20. Overview of MongoDB M ap R ed u c e map = function() { for (var i in this.tags) { emit(this.tags[i], 1); } } reduce = function(key, values) { var count = 0; for (var i in values) { count += current[i]; } return count; } // 1.8+ must set out collection db.posts.mapReduce(map, reduce, {out: 'tags_count'})
  • 21. Overview of MongoDB M ap R ed u c e > db.tags_count.find() {"_id" : "MongoDB", "value" : 4} {"_id" : "Map/Reduce", "value" : 2} {"_id" : "Recipe", "value" : 7} {"_id" : "Group", "value" : 1}
  • 22. Overview of MongoDB Gr id F S Upload image var gridStore = new GridStore(db, filename, "w"); gridStore.open(function(err, gridStore) { gridStore.write(imageData, function(err, gridStore) { gridStore.close(function(err, result) { console.log(result._id); users.update({_id: userId}, {$set: {avatarId: result._id}}); }); }); }); HTML <img src="http://asset.url/gridfs/{{ user.avatarId }}" /> Use nginx-gridfs
  • 23. Overview of MongoDB R ep lic at ion and S h ar d in g
  • 24. Nice
  • 26. Nest ed c allb ac k s, an d n ot D R Y ? var database = new mongo.Db('testdb', new mongo.Server('localhost', 27017)); database.open(function(err, db) { if(err) return handle(err); db.collection('user', function(err, collection) { if(err) return handle(err); collection.find({}, function(err, cursor) { if(err) return handle(err); cursor.toArray(function(err, users) { if(err) return handle(err); doSomething(users); }); }); }); });
  • 27. How t o exp or t c ollec t ion var database = new mongo.Db('testdb', new mongo.Server('localhost', 27017)); database.open(function(err, db){ db.collection('posts', function(err, posts) { // can't export here? }); }); exports.posts = ?
  • 28. How t o sh ar e c ollec t ion ob jec t controllers/user.js var database = new mongo.Db('testdb', new mongo.Server('localhost', 27017)); //... database.open(function(err, db){ db.collection('user', function(err, userColl){ userColl.find({}, function(err, cursor){ if(err) return handle(err); cursor.toArray(function(err, users){ res.render('/user.html', {users: users}); }) }); }); });
  • 29. How t o sh ar e c ollec t ion ob jec t controllers/book.js var database = new mongo.Db('testdb', new mongo.Server('localhost', 27017)); //... database.open(function(err, db){ db.collection('user', function(err, userColl){ userColl.findOne({_id: book.author_id}, function(err, author){ res.render('/book.html', {book: book, author: author}); }); }); });
  • 31. How ab ou t t h is config.js exports.db = mongo.db('mongo://localhost:27017/testdb')
  • 32. An d t h is controllers/user.js var db = require('../config').db; db.collection('user').find({}).toArray(function(err, users){ if(err) return handle(err); res.render('/user.html', {users: users}); });
  • 33. An d t h is controllers/book.js var db = require('../config').db; db.collection('user').findOne({_id, book.author_id}, function(err, author){ if(err) return handle(err); res.render('/book.html', {book: book, author: author}); });
  • 35. Patterns of mongoskin var mongoskin = require('mongoskin'); var db = mongoskin.db('mongo://localhost:27017/testdb'); db.bind('users'); db.bind('books'); db.users.find({}).limit(10).sort({name:-1}).toArray(function(err, users){ }); db.books.update({_id: bookId}, {$inc: {votes: 1}}, function(err, reply){ });
  • 36. Patterns of mongoskin Pr oxy all m et h od s node-mongoskin var skindb = mongoskin.db('mongo://localhost:27017/testdb') function callback(err, reply){} skindb.addUser('foo', 'bar', callback); node-mongodb-native var db = new mongodb.Db('testdb', new mongodb.Server('localhost', 27017)); function callback(err, reply){} db.open(function(err, db){ if(err) return callback(err); db.addUser('foo', 'bar', callback); });
  • 37. Patterns of mongoskin SkinClass hold all parameters to open it var SkinDb = exports.SkinDb = function(db, username, password) { this.db = db; this.username = username; this.password = password; this.state = STATE_CLOSE; this.emitter = new events.EventEmitter(); this._collections = {}; };
  • 38. Patterns of mongoskin Proxy all methods inside open for (var name in Db.prototype) { SkinDb.prototype[name] = function() { var args = Array.prototype.slice.call(arguments); this.open(function(err, db) { if (err) { return args[args.length - 1](err);//callback(err) } else { return Db.prototype[name].apply(db, args); } }); }; }
  • 39. Patterns of mongoskin Open only on c e (pseudo-code) SkinDb.prototype.open = function(fn) { switch (this.state) { case STATE_OPEN: return fn(null, this.db); case STATE_OPENNING: // if call 'open' method multi times before opened return this.emitter.addListener('open', fn); case STATE_CLOSE: this.state = STATE_OPENNING; var that = this; this.db.open(function(err, db){ that.db = db; fn(err, db); that.state = STATE_OPEN; that.emitter.emit('open', err, db); }); }
  • 40. } }; Patterns of mongoskin R et u r n s S k in Collec t ion SkinDb.prototype.collection = function(name) { var collection = this._collections[name]; if (!collection) { this._collections[name] = collection = new SkinCollection(this, name); } return collection; };
  • 41. Patterns of mongoskin S k in Collec t ion var SkinCollection = exports.SkinCollection = function(skinDb, collectionName) { this.skinDb = skinDb; this.collectionName = collectionName; this.collection; this.state = STATE_CLOSE; this.internalHint; var that = this; this.__defineGetter__('hint', function() { return this.internalHint; }); this.__defineSetter__('hint', function(value) { this.internalHint = value; this.open(function(err, collection) { collection.hint = value; that.internalHint = collection.hint; }); }); this.emitter = new events.EventEmitter(); }
  • 42. } Patterns of mongoskin Pr oxy all m et h od s in sid e S k in Collec t ion . op en for (var name in Collection.prototype) { SkinCollection.prototype[name] = function() { var args = Array.prototype.slice.call(arguments); this.open(function(err, collection) { if (err) { args[args.length - 1](err);// callback(err) } else { Collection.prototype[name].apply(collection, args); } }); }; }
  • 43. Patterns of mongoskin S k in Collec t ion . op en SkinCollection.prototype.open = function(callback) { //... var that = this; this.skinDb.open(function(err, db){ db.collection(that.collectionName, function(err, collection){ this.nativeCollection = collection; callback(err, collection); } }); }
  • 44. Patterns of mongoskin R et u r n s S k in Cu r sor if n o c allb ac k SkinCollection.prototype.find = function() { var args = Array.prototype.slice.call(arguments); if (args.length > 0 && typeof(args[args.length - 1]) === 'function') { this._find.apply(this, args); }else { return new SkinCursor(null, this, args); } }; An d so d o w it h S k in Cu r sor
  • 45. Patterns of mongoskin Pat t er n s of m on g osk in SkinClass contains all parameters to get NativeObject Proxy all method inside callback of op en ( ) Make open() method cache result Return SkinClass object to chain execution
  • 46. Reference MongoDB The Definitive Guide MongoDB Docs http://www.mongodb.org/display/DOCS/Home MongoDB Cookbook http://cookbook.mongodb.org/ Node mongodb https://github.com/christkv/node-mongodb-native Mongoskin https://github.com/guileen/node-mongoskin
  • 47. Thank you 桂糊涂@weibo guileen@gmail.com