mongoskin - guilin

47
by 桂林

Upload: jacksontian

Post on 10-May-2015

4.648 views

Category:

Technology


2 download

DESCRIPTION

NodeParty-SH-1

TRANSCRIPT

Page 1: Mongoskin - Guilin

by 桂林

Page 2: Mongoskin - Guilin

All languages usedAll languages usedAll languages usedAll languages used

Browser script: javaScriptjavaScriptjavaScriptjavaScript

Server script: javaScriptjavaScriptjavaScriptjavaScript

Database script: javaScriptjavaScriptjavaScriptjavaScript

Page 3: Mongoskin - Guilin

All languages usedAll languages usedAll languages usedAll languages used

Browser script: javaScriptjavaScriptjavaScriptjavaScript

Server script: javaScriptjavaScriptjavaScriptjavaScript

Database script: javaScriptjavaScriptjavaScriptjavaScript

Page 4: Mongoskin - Guilin

Overview of MongoDB

Patterns of mongoskin

Page 5: Mongoskin - Guilin

Why MongoDB Why MongoDB Why MongoDB Why MongoDB

AgileAgileAgileAgile and ScalableScalableScalableScalable

Page 6: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBMySQLMySQLMySQLMySQL

postsid

commentsid

post_id

tagsid

name

posts_tagspost_id

tag_id

Page 7: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDB

Database >> Database

Table >> Collection

Row >> Document

Page 8: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBMongoDBMongoDBMongoDBMongoDB{ _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: '[email protected]', body: '...', created: new Date('09/17/2011') } ], tags: ['MongoDB', 'database']}

Page 9: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBGet collect ionGet collect ionGet collect ionGet collect ionMongoDB shellposts = db.posts

NodeJSvar 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 });});

Page 10: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBInsertInsertInsertInsertMongoDB shellvar doc = {title: 'test posts', ...};posts.insert(doc);

NodeJSposts.insert(doc, function(err, reply){ // error or done});

Page 11: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBQueryQueryQueryQueryMongoDB shellposts.find({"comments.author", "bob"})

NodeJSposts.find({"comments.author", "bob"}, function(err, cursor){ cursor.toArray(function(err, docs){ // found docs here });});

Page 12: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBQuery operatorQuery operatorQuery operatorQuery operator{<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, …

Page 13: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBUpdateUpdateUpdateUpdateMongoDB shellposts.update({_id: doc.id}, {$inc: {votes: 1}})

NodeJSposts.update({_id: doc.id}, {$inc: {votes: 1}}, function(err, count){});

Page 14: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBModif ier operat ionsModif ier operat ionsModif ier operat ionsModif ier operat ions

$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

Page 15: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBRemoveRemoveRemoveRemoveMongoDB shellposts.remove({author: 'bob'})

NodeJSposts.remove({author: 'bob'}, function(err, reply){})

Page 16: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBIndexIndexIndexIndexMongoDB shellposts.ensureIndex({author:1})posts.ensureIndex({slug: 1 }, {unique: true});db.things.ensureIndex( {firstname: 1, lastname: 1}, {unique: true, background:true});

NodeJSposts.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){});

Page 17: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBGeospatialGeospatialGeospatialGeospatial{ 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 = 10db.places.find({"loc" : {"$within" : {"$center" : [center, radius]}}})

Page 18: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBOptimizat ionOptimizat ionOptimizat ionOptimizat 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

Page 19: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBAggregationAggregationAggregationAggregationposts.count( {author: 'bob'} )posts.distinct("author")

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

MongoDB groupdb.coll.group( {key: { a:true, b:true }, cond: { active:1 }, reduce: function(obj, out) { out.csum += obj.c; }, initial: { csum: 0 } });

Page 20: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBMapReduceMapReduceMapReduceMapReducemap = 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 collectiondb.posts.mapReduce(map, reduce, {out: 'tags_count'})

Page 21: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBMapReduceMapReduceMapReduceMapReduce> db.tags_count.find(){"_id" : "MongoDB", "value" : 4}{"_id" : "Map/Reduce", "value" : 2}{"_id" : "Recipe", "value" : 7}{"_id" : "Group", "value" : 1}

Page 22: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBGridFSGridFSGridFSGridFSUpload imagevar 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

Page 23: Mongoskin - Guilin

Overview of MongoDB Overview of MongoDB Overview of MongoDB Overview of MongoDBReplicat ionReplicat ionReplicat ionReplicat ion and ShardingShardingShardingSharding

Page 24: Mongoskin - Guilin

NiceNiceNiceNice

Page 25: Mongoskin - Guilin

NiceNiceNiceNice ,but nodenodenodenode

Page 26: Mongoskin - Guilin

Nested callbacks, and not DRY?Nested callbacks, and not DRY?Nested callbacks, and not DRY?Nested callbacks, and not DRY?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); }); }); });});

Page 27: Mongoskin - Guilin

How to export collect ionHow to export collect ionHow to export collect ionHow to export collect ionvar 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 = ?

Page 28: Mongoskin - Guilin

How to share collect ion objectHow to share collect ion objectHow to share collect ion objectHow to share collect ion objectcontrollers/user.jsvar 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}); }) });

});});

Page 29: Mongoskin - Guilin

How to share collect ion objectHow to share collect ion objectHow to share collect ion objectHow to share collect ion objectcontrollers/book.jsvar 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}); }); });});

Page 30: Mongoskin - Guilin

RedsignRedsignRedsignRedsign the API

Page 31: Mongoskin - Guilin

How about thisHow about thisHow about thisHow about thisconfig.jsexports.db = mongo.db('mongo://localhost:27017/testdb')

Page 32: Mongoskin - Guilin

And thisAnd thisAnd thisAnd thiscontrollers/user.jsvar db = require('../config').db;db.collection('user').find({}).toArray(function(err, users){ if(err) return handle(err); res.render('/user.html', {users: users});});

Page 33: Mongoskin - Guilin

And thisAnd thisAnd thisAnd thiscontrollers/book.jsvar 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});});

Page 34: Mongoskin - Guilin

It’s MongoSkinMongoSkinMongoSkinMongoSkin

Page 35: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinvar 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){});

Page 36: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinProxy all methodsProxy all methodsProxy all methodsProxy all methodsnode-mongoskinvar skindb = mongoskin.db('mongo://localhost:27017/testdb')function callback(err, reply){}skindb.addUser('foo', 'bar', callback);

node-mongodb-nativevar 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);});

Page 37: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinSkinClass hold all parameters to open itvar 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 = {};};

Page 38: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinProxy all methods inside openfor (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); } }); };}

Page 39: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinOpen only onceonceonceonce (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); }); }

Page 40: Mongoskin - Guilin

}}; Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin

Returns SkinCollect ionReturns SkinCollect ionReturns SkinCollect ionReturns SkinCollect ionSkinDb.prototype.collection = function(name) { var collection = this._collections[name]; if (!collection) { this._collections[name] = collection = new SkinCollection(this, name); } return collection;};

Page 41: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinSkinCollect ionSkinCollect ionSkinCollect ionSkinCollect ionvar 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();}

Page 42: Mongoskin - Guilin

}

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinProxy all methods inside SkinCollect ion.openProxy all methods inside SkinCollect ion.openProxy all methods inside SkinCollect ion.openProxy all methods inside SkinCollect ion.openfor (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); } }); };}

Page 43: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinSkinCollect ion.openSkinCollect ion.openSkinCollect ion.openSkinCollect ion.openSkinCollection.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); } });}

Page 44: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinReturns SkinCursor if no callbackReturns SkinCursor if no callbackReturns SkinCursor if no callbackReturns SkinCursor if no callbackSkinCollection.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); }};

And so do with SkinCursorAnd so do with SkinCursorAnd so do with SkinCursorAnd so do with SkinCursor

Page 45: Mongoskin - Guilin

Patterns of mongoskin Patterns of mongoskin Patterns of mongoskin Patterns of mongoskinPatterns of mongoskinPatterns of mongoskinPatterns of mongoskinPatterns of mongoskin

SkinClass contains all parameters to get NativeObject

Proxy all method inside callback of open()open()open()open()

Make open() method cache result

Return SkinClass object to chain execution

Page 46: Mongoskin - Guilin

ReferenceReferenceReferenceReference

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

Page 47: Mongoskin - Guilin

Thank youThank youThank youThank you桂糊涂@weibo

[email protected]