SlideShare a Scribd company logo
1 of 67
An introduction to the
node.js mongo driver
     Christian Amor Kvalheim
• Asynchronous Javascript platform built on
  top of V8
• Single-threaded
• Package manager
• Awesome
Hello World Server
var http = require('http');

http.createServer(
  function (req, res) {
    res.writeHead(200,
      {'Content-Type': 'text/plain'});
    res.end('Hello Worldn');
  }).listen(8124, "127.0.0.1");
Hello World Server
                                     Load the http library
var http = require('http');

http.createServer(
  function (req, res) {
    res.writeHead(200,
      {'Content-Type': 'text/plain'});
    res.end('Hello Worldn');
  }).listen(8124, "127.0.0.1");
Hello World Server
                                     Load the http library
var http = require('http');
                                     Set up the connection
http.createServer(                          handler
  function (req, res) {
    res.writeHead(200,
      {'Content-Type': 'text/plain'});
    res.end('Hello Worldn');
  }).listen(8124, "127.0.0.1");
How to get started

• Install node.js (from source or package)
• Install npm (node package manager)
• Create an empty directory
• npm install mongodb
• npm install express
Let’s do some code


• Using Express and Mongo
• Textmate basic.js
Picking it apart
var db = new Db('node-mongo-examples', new Server(host, port, {}),
{native_parser:false});




db.open(function(err, db) { ...
  .....
  app.listen(8124);




var app = express.createServer();

app.get('/', function(req, res){
  res.send('Hello World');
});
Picking it apart
  Creates a db using the js bson parser
var db = new Db('node-mongo-examples', new Server(host, port, {}),
{native_parser:false});




db.open(function(err, db) { ...
  .....
  app.listen(8124);




var app = express.createServer();

app.get('/', function(req, res){
  res.send('Hello World');
});
Picking it apart
  Creates a db using the js bson parser
var db = new Db('node-mongo-examples', new Server(host, port, {}),
{native_parser:false});



  Opens the connection to the db
db.open(function(err, db) { ...
  .....
  app.listen(8124);




var app = express.createServer();

app.get('/', function(req, res){
  res.send('Hello World');
});
Picking it apart
  Creates a db using the js bson parser
var db = new Db('node-mongo-examples', new Server(host, port, {}),
{native_parser:false});



  Opens the connection to the db
db.open(function(err, db) { ...
  .....
  app.listen(8124);


 The server is now running with access to
      the mongo server connection
var app = express.createServer();

app.get('/', function(req, res){
  res.send('Hello World');
});
Let’s add some meat


• CRUD operations
• Textmate basic_2.js
Picking it apart
// Create method
app.post('/location', function(req, res) {
  geoCodeDecorateObject(req.body.address, {description:req.body.description},
function(err, object) {
    db.collection('locations', function(err, collection) {

      // Insert doc
      collection.insert(object, {safe:true}, function(err, result) {

        // Fetch all docs for rendering of list
        collection.find({}).toArray(function(err, items) {
           res.render('./basic_2.jade', {locals: {locations:items}});
        })
      });
    });
  });
});
Picking it apart
Geo Encode Address
// Create method
app.post('/location', function(req, res) {
  geoCodeDecorateObject(req.body.address, {description:req.body.description},
function(err, object) {
    db.collection('locations', function(err, collection) {

      // Insert doc
      collection.insert(object, {safe:true}, function(err, result) {

        // Fetch all docs for rendering of list
        collection.find({}).toArray(function(err, items) {
           res.render('./basic_2.jade', {locals: {locations:items}});
        })
      });
    });
  });
});
Picking it apart
       Geo Encode Address
       // Create method
       app.post('/location', function(req, res) {
         geoCodeDecorateObject(req.body.address, {description:req.body.description},
       function(err, object) {
           db.collection('locations', function(err, collection) {

             // Insert doc
             collection.insert(object, {safe:true}, function(err, result) {

               // Fetch all docs for rendering of list
               collection.find({}).toArray(function(err, items) {
                  res.render('./basic_2.jade', {locals: {locations:items}});
               })

Insert record, safe ensures that we trap any
             });
           });
         });
   errors by doing a error check against
       });


                  mongodb
Picking it apart
     // Create method
     app.post('/location', function(req, res) {
       geoCodeDecorateObject(req.body.address, {description:req.body.description},
     function(err, object) {
         db.collection('locations', function(err, collection) {

           // Insert doc
           collection.insert(object, {safe:true}, function(err, result) {

             // Fetch all docs for rendering of list
             collection.find({}).toArray(function(err, items) {
                res.render('./basic_2.jade', {locals: {locations:items}});
             })
           });
         });
       });
     find all records from the locations
     });


collection. Find returns a cursor that allows
      for stepping through doucments
Safe or not

• Mongo Insert/Update/Delete are async
• 2nd call to lastError required to check for
  the success of the operation
• safe option ensures the second error call
• you can also run the driver in strict mode
Let’s add some meat


• CRUD operations
• Textmate basic_3.js
Picking it apart
// Delete method
app.del('/location', function(req, res) {
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {
    collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) {

       // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_3.jade', {locals: {locations:items}});
      })
    })
  });
});
Picking it apart
                                                  Convert hex string to
// Delete method                                       objectID
app.del('/location', function(req, res) {
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {
    collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) {

       // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_3.jade', {locals: {locations:items}});
      })
    })
  });
});
Picking it apart
                                                  Convert hex string to
// Delete method                                       objectID
app.del('/location', function(req, res) {
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {
    collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) {

       // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_3.jade', {locals: {locations:items}});

    })
      })
                Remove the document using the specific id
  });
});
                         passed in, using safe.
Let’s add some meat


• CRUD operations
• Textmate basic_4.js
Picking it apart
// Get method
app.get('/location', function(req, res) {
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {

    collection.findOne({_id:id}, function(err, item) {

      // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_4.jade', {locals: {locations:items, location:item}});
      })
    })
  });
});
Picking it apart
                                  Convert hex string to
// Get method
app.get('/location', function(req, res) {
                                          objectID
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {

    collection.findOne({_id:id}, function(err, item) {

      // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_4.jade', {locals: {locations:items, location:item}});
      })
    })
  });
});
Picking it apart
                                  Convert hex string to
// Get method
app.get('/location', function(req, res) {
                                          objectID
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {

    collection.findOne({_id:id}, function(err, item) {

      // Fetch all docs for rendering of list
      collection.find({}).toArray(function(err, items) {
         res.render('./basic_4.jade', {locals: {locations:items, location:item}});

    })
      })
                          Locate one document by id
  });
});
Let’s add some meat


• CRUD operations
• Textmate basic_5.js
Picking it apart
// Update method
app.put('/location', function(req, res) {
  var id = ObjectID.createFromHexString(req.body.id);
  db.collection('locations', function(err, collection) {

   collection.findOne({_id:id}, function(err, object) {
     object.description = req.body.description;
     object.address = req.body.address;

     geoCodeDecorateObject(req.body.address, object, function(err, object) {

        collection.update({_id:object._id}, object, {safe:true}, function(err,
numberOfUpdatedObjects) {

            // Fetch all docs for rendering of list
            collection.find({}).toArray(function(err, items) {
               res.render('./basic_5.jade', {locals: {locations:items}});
            })
          })
     })
Picking it apart
// Update method
app.put('/location', function(req, res) {
                                                 Locate object we wish
  var id = ObjectID.createFromHexString(req.body.id);
                                                       to modify
  db.collection('locations', function(err, collection) {

   collection.findOne({_id:id}, function(err, object) {
     object.description = req.body.description;
     object.address = req.body.address;

     geoCodeDecorateObject(req.body.address, object, function(err, object) {

        collection.update({_id:object._id}, object, {safe:true}, function(err,
numberOfUpdatedObjects) {

            // Fetch all docs for rendering of list
            collection.find({}).toArray(function(err, items) {
               res.render('./basic_5.jade', {locals: {locations:items}});
            })
          })
     })
Picking it apart
// Update method
app.put('/location', function(req, res) {
                                                 Locate object we wish
  var id = ObjectID.createFromHexString(req.body.id);
                                                       to modify
  db.collection('locations', function(err, collection) {

   collection.findOne({_id:id}, function(err, object) {
     object.description = req.body.description;
     object.address = req.body.address;

     geoCodeDecorateObject(req.body.address, object, function(err, object) {

        collection.update({_id:object._id}, object, {safe:true}, function(err,
numberOfUpdatedObjects) {

            // Fetch all docs for rendering of list
            collection.find({}).toArray(function(err, items) {
               res.render('./basic_5.jade', {locals: {locations:items}});
            })

     })
          })   Update document using the id to select
                     what document to update
Let’s add some meat


• Final with search
• Textmate basic_6.js
Picking it apart
db.open(function(err, db) {
  if(err) throw err

  // !!! CHANGE
  db.ensureIndex("locations", {loc:"2d"}, function(err, result) {
    if(err) throw err

    app.listen(8124);
  })
});
Picking it apart
db.open(function(err, db) {
  if(err) throw err

  // !!! CHANGE
  db.ensureIndex("locations", {loc:"2d"}, function(err, result) {
    if(err) throw err

    app.listen(8124);
  })
});    Ensures there is a 2d geospatial index on
       the attribute loc on any document in the
                  locations collection
Picking it apart
var geoCodeDecorateObject = function(address, object, callback) {
  var googleGeoCodeApi = {host: 'maps.googleapis.com',
    port: 80,path: '/maps/api/geocode/json?sensor=false&address=' +
escape(address),
    method: 'GET' };

  var clientReq = http.get(googleGeoCodeApi, function(clientRes) {
    var data = [];
    clientRes.on('data', function(chunk) {
      data.push(chunk.toString());
    });
    clientRes.on('end', function() {
      var googleObject = JSON.parse(data.join(''));

     object.address = address;
     object.geodata = googleObject.results.pop();

      // !!! CHANGE
      object.loc = {long:object.geodata.geometry.location.lng,
lat:object.geodata.geometry.location.lat};

     callback(null, object);
   });
Picking it apart
var geoCodeDecorateObject = function(address, object, callback) {
  var googleGeoCodeApi = {host: 'maps.googleapis.com',
    port: 80,path: '/maps/api/geocode/json?sensor=false&address=' +
escape(address),
    method: 'GET' };

  var clientReq = http.get(googleGeoCodeApi, function(clientRes) {
    var data = [];
    clientRes.on('data', function(chunk) {
      data.push(chunk.toString());
                                                          We are adding a loc
    });
    clientRes.on('end', function() {
                                                             attribute to all
      var googleObject = JSON.parse(data.join(''));
                                                            documents with
     object.address = address;
     object.geodata = googleObject.results.pop();            longtidude and
      // !!! CHANGE                                       latitude in the right
      object.loc = {long:object.geodata.geometry.location.lng,
lat:object.geodata.geometry.location.lat};               order for mongodb to
     callback(null, object);
   });
                                                                  search
Picking it apart
// !!! CHANGE
// Search option
app.post('/search', function(req, res) {
  geoCodeDecorateObject(req.body.address, {}, function(err, object) {
    // Unpack geo object
    var long = object.geodata.geometry.location.lng;
    var lat = object.geodata.geometry.location.lat

    db.collection('locations', function(err, collection) {
      collection.find({loc : {'$near': [long, lat], '$maxDistance':
parseFloat(req.body.distance)}}).toArray(function(err, geoItems) {
        // Fetch all docs for rendering of list
        collection.find({}).toArray(function(err, items) {
           res.render('./basic_6.jade', {locals: {locations:items,
results:geoItems}});
        })
      });
    });
  });
});
Picking it apart
                                                  Encode address for
// !!! CHANGE
// Search option                                      searching
app.post('/search', function(req, res) {
  geoCodeDecorateObject(req.body.address, {}, function(err, object) {
    // Unpack geo object
    var long = object.geodata.geometry.location.lng;
    var lat = object.geodata.geometry.location.lat

    db.collection('locations', function(err, collection) {
      collection.find({loc : {'$near': [long, lat], '$maxDistance':
parseFloat(req.body.distance)}}).toArray(function(err, geoItems) {
        // Fetch all docs for rendering of list
        collection.find({}).toArray(function(err, items) {
           res.render('./basic_6.jade', {locals: {locations:items,
results:geoItems}});
        })
      });
    });
  });
});
Picking it apart
                                                  Encode address for
// !!! CHANGE
// Search option                                      searching
app.post('/search', function(req, res) {
  geoCodeDecorateObject(req.body.address, {}, function(err, object) {
    // Unpack geo object
    var long = object.geodata.geometry.location.lng;
    var lat = object.geodata.geometry.location.lat

    db.collection('locations', function(err, collection) {
      collection.find({loc : {'$near': [long, lat], '$maxDistance':
parseFloat(req.body.distance)}}).toArray(function(err, geoItems) {
        // Fetch all docs for rendering of list
        collection.find({}).toArray(function(err, items) {
           res.render('./basic_6.jade', {locals: {locations:items,
results:geoItems}});
        })
      });
                    Search for all items $near our address at
    });
  });
                                    $maxDistance
});
Other features


•   Cursors
•   Grid FS
Cursors

• toArray Function
• each Function
• streamRecords Function
toArray

collection.find().toArray(function(err, documents){
  test.deepEqual([1, 2, 3], documents[0].b);
  // Let's close the db
  test.done();
});
toArray
                       Fetches all docs in one go
                        for the query. Use with
                                caution
collection.find().toArray(function(err, documents){
  test.deepEqual([1, 2, 3], documents[0].b);
  // Let's close the db
  test.done();
});
each

collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){
    if(item != null) {
       // Do work
    } else {
       // Finished
    }
});
each
                                  Fetches docs in batches and
                                  allows iteration over results

collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){
    if(item != null) {
       // Do work
    } else {
       // Finished
    }
});
each
                                  Fetches docs in batches and
                                  allows iteration over results

collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){
    if(item != null) {
       // Do work
    } else {
       // Finished
    }
});
                            Returns null when no more
                                 results available
streamRecords
  var stream = collection.find({}, {'limit' :
  3}).streamRecords();

stream.on('end', function() {
  // No more results in the pipe
});

stream.on('data',function(data){
  // Item
});
streamRecords
  var stream = collection.find({}, {'limit' :
  3}).streamRecords();

stream.on('end', function() {
  // No more results in the pipe
});

stream.on('data',function(data){
  // Item
});

                          When an item is ready the
                           event ‘data’ is triggered
streamRecords
  var stream = collection.find({}, {'limit' :
  3}).streamRecords();
                                      When no more items
stream.on('end', function() {            are available
  // No more results in the pipe
});

stream.on('data',function(data){
  // Item
});

                          When an item is ready the
                           event ‘data’ is triggered
streamRecords
  var stream = collection.find({}, {'limit' :
  3}).streamRecords();
                                      When no more items
stream.on('end', function() {            are available
  // No more results in the pipe
});


                                      REFERED
                                     P
stream.on('data',function(data){
  // Item
});

                          When an item is ready the
                           event ‘data’ is triggered
Grid FS

• Write and read a file
• Stream a file
Write a file
var gridStore = new GridStore(client, 'test_gs_writing_file', 'w');

gridStore.open(function(err, gridStore) {

gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) {




  GridStore.read(client, 'test_gs_writing_file', function(err, fileData) {
  });
Write a file
var gridStore = new GridStore(client, 'test_gs_writing_file', 'w');

gridStore.open(function(err, gridStore) {

gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) {


                       Writes the file in chunks to
                       mongodb (avoids freezing the
                          eventloop in node.js)

  GridStore.read(client, 'test_gs_writing_file', function(err, fileData) {
  });
Write a file
var gridStore = new GridStore(client, 'test_gs_writing_file', 'w');

gridStore.open(function(err, gridStore) {

gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) {


                       Writes the file in chunks to
                       mongodb (avoids freezing the
                          eventloop in node.js)

  GridStore.read(client, 'test_gs_writing_file', function(err, fileData) {
  });



                        Read the whole file. Careful with the
                                    memory
Stream a file
var gridStore = new GridStore(client, "test_gs_read_stream", "r");

gridStore.open(function(err, gs) {
  var stream = gs.stream(true);




 stream.on("data", function(chunk) {
   // Received a chunk of data
 });




  stream.on("end", function() {
    // Finished streaming
  });
});
Stream a file
var gridStore = new GridStore(client, "test_gs_read_stream", "r");

gridStore.open(function(err, gs) {
  var stream = gs.stream(true);

                   Receive a chunk and do something
 stream.on("data", function(chunk) {
   // Received a chunk of data
 });




  stream.on("end", function() {
    // Finished streaming
  });
});
Stream a file
var gridStore = new GridStore(client, "test_gs_read_stream", "r");

gridStore.open(function(err, gs) {
  var stream = gs.stream(true);

                   Receive a chunk and do something
 stream.on("data", function(chunk) {
   // Received a chunk of data
 });
                    Finshed stream the file

  stream.on("end", function() {
    // Finished streaming
  });
});
Stream a file
var gridStore = new GridStore(client, "test_gs_read_stream", "r");

gridStore.open(function(err, gs) {
  var stream = gs.stream(true);

                   Receive a chunk and do something
 stream.on("data", function(chunk) {
   // Received a chunk of data
 });
                    Finshed stream the file

  stream.on("end", function() {
    // Finished streaming              PR EFE RED
  });
});
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i});
}




collection.count(function(err, count) {
  // count is > 0 <= 100
});
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i});
}


                    All executed in parallel, non-
                   deterministic end of execution
collection.count(function(err, count) {
  // count is > 0 <= 100
});
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i});
}


                    All executed in parallel, non-
                   deterministic end of execution
collection.count(function(err, count) {
  // count is > 0 <= 100
});

                   All inserts MAY have been written
                   to disk so passes most of the time.
                        But with Pooling NO WAY
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i}, {safe:true}, function(err, result) {
    // Do something
  });
}

??????????????????????????????
collection.count(function(err, count) {
  // count is > 0 <= 100
});
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i}, {safe:true}, function(err, result) {
    // Do something
  });
}                         How do we handle the callbacks
??????????????????????????????
collection.count(function(err, count) {
  // count is > 0 <= 100
});
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i}, {safe:true}, function(err, result) {
    // Do something
  });
}                         How do we handle the callbacks
??????????????????????????????
collection.count(function(err, count) {
  // count is > 0 <= 100
});


                      How do we get to this code ??????
Typical starting problems
for(var i = 0; i < 100; i++) {
  collection.insert({'i':i}, {safe:true}, function(err, result) {
    // Do something
  });
}                         How do we handle the callbacks
??????????????????????????????
collection.count(function(err, count) {
  // count is > 0 <= 100
});


                      How do we get to this code ??????

       Many possible solutions
My Choosen Solution
                https://github.com/creationix/step
    Step(
      function insert() {
         var group = this.group();
         for(var i = 0; i < 100; i++) {
           collection.insert({'i':i}, {safe:true}, group());
         }
      },




    function finished() {
      collection.count(function(err, count) {
        // Count is 100 :)
      });
    }
)
My Choosen Solution
                https://github.com/creationix/step
    Step(
      function insert() {
         var group = this.group();
         for(var i = 0; i < 100; i++) {
           collection.insert({'i':i}, {safe:true}, group());
         }
      },                 Ensures all the inserts are finished
                          before calling the next function
    function finished() {
      collection.count(function(err, count) {
        // Count is 100 :)
      });
    }
)
My Choosen Solution
                https://github.com/creationix/step
    Step(
      function insert() {
         var group = this.group();
         for(var i = 0; i < 100; i++) {
           collection.insert({'i':i}, {safe:true}, group());
         }
      },                 Ensures all the inserts are finished
                          before calling the next function
    function finished() {
      collection.count(function(err, count) {
        // Count is 100 :)
      });
    }
)                         When all inserts are done :)
DONE
                   Code on
https://github.com/christkv/mongodb-hamburg

More Related Content

What's hot

Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationAlex Hardman
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreNicolas Carlo
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeMongoDB
 
Writing Your App Swiftly
Writing Your App SwiftlyWriting Your App Swiftly
Writing Your App SwiftlySommer Panage
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityDerek Lee Boire
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applicationsSkills Matter
 
Cycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveCycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveEugene Zharkov
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashBret Little
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2RORLAB
 
Hd insight programming
Hd insight programmingHd insight programming
Hd insight programmingCasear Chu
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesCody Yun
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012Amazon Web Services
 
Formacion en movilidad: Conceptos de desarrollo en iOS (IV)
Formacion en movilidad: Conceptos de desarrollo en iOS (IV) Formacion en movilidad: Conceptos de desarrollo en iOS (IV)
Formacion en movilidad: Conceptos de desarrollo en iOS (IV) Mobivery
 

What's hot (20)

Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
Config BuildConfig
Config BuildConfigConfig BuildConfig
Config BuildConfig
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Using Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data VisualisationUsing Arbor/ RGraph JS libaries for Data Visualisation
Using Arbor/ RGraph JS libaries for Data Visualisation
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscore
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
Writing Your App Swiftly
Writing Your App SwiftlyWriting Your App Swiftly
Writing Your App Swiftly
 
Minimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team ProductivityMinimizing Decision Fatigue to Improve Team Productivity
Minimizing Decision Fatigue to Improve Team Productivity
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Cycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveCycle.js: Functional and Reactive
Cycle.js: Functional and Reactive
 
Hidden rocks in Oracle ADF
Hidden rocks in Oracle ADFHidden rocks in Oracle ADF
Hidden rocks in Oracle ADF
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
 
Hd insight programming
Hd insight programmingHd insight programming
Hd insight programming
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and Classes
 
Lodash js
Lodash jsLodash js
Lodash js
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
 
Formacion en movilidad: Conceptos de desarrollo en iOS (IV)
Formacion en movilidad: Conceptos de desarrollo en iOS (IV) Formacion en movilidad: Conceptos de desarrollo en iOS (IV)
Formacion en movilidad: Conceptos de desarrollo en iOS (IV)
 

Viewers also liked

Building Applications using MongoDB, Node.js and Socket.io
Building Applications using MongoDB, Node.js and Socket.ioBuilding Applications using MongoDB, Node.js and Socket.io
Building Applications using MongoDB, Node.js and Socket.ioMongoDB
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
Python and pandas as back end to real-time data driven applications by Giovan...
Python and pandas as back end to real-time data driven applications by Giovan...Python and pandas as back end to real-time data driven applications by Giovan...
Python and pandas as back end to real-time data driven applications by Giovan...PyData
 
Geospatial Indexing and Querying with MongoDB
Geospatial Indexing and Querying with MongoDBGeospatial Indexing and Querying with MongoDB
Geospatial Indexing and Querying with MongoDBGrant Goodale
 
Introduction to node js - From "hello world" to deploying on azure
Introduction to node js - From "hello world" to deploying on azureIntroduction to node js - From "hello world" to deploying on azure
Introduction to node js - From "hello world" to deploying on azureColin Mackay
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS Ganesh Kondal
 
7 Stages of Scaling Web Applications
7 Stages of Scaling Web Applications7 Stages of Scaling Web Applications
7 Stages of Scaling Web ApplicationsDavid Mitzenmacher
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with ExamplesGabriele Lana
 
Better Software—Faster: Ten Best Practices from Sequoia's Microservices Summit
Better Software—Faster: Ten Best Practices from Sequoia's Microservices SummitBetter Software—Faster: Ten Best Practices from Sequoia's Microservices Summit
Better Software—Faster: Ten Best Practices from Sequoia's Microservices SummitSequoia Capital
 

Viewers also liked (12)

Building Applications using MongoDB, Node.js and Socket.io
Building Applications using MongoDB, Node.js and Socket.ioBuilding Applications using MongoDB, Node.js and Socket.io
Building Applications using MongoDB, Node.js and Socket.io
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
Knonex
KnonexKnonex
Knonex
 
Python and pandas as back end to real-time data driven applications by Giovan...
Python and pandas as back end to real-time data driven applications by Giovan...Python and pandas as back end to real-time data driven applications by Giovan...
Python and pandas as back end to real-time data driven applications by Giovan...
 
Geospatial Indexing and Querying with MongoDB
Geospatial Indexing and Querying with MongoDBGeospatial Indexing and Querying with MongoDB
Geospatial Indexing and Querying with MongoDB
 
Introduction to node js - From "hello world" to deploying on azure
Introduction to node js - From "hello world" to deploying on azureIntroduction to node js - From "hello world" to deploying on azure
Introduction to node js - From "hello world" to deploying on azure
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS
 
Best node js course
Best node js courseBest node js course
Best node js course
 
7 Stages of Scaling Web Applications
7 Stages of Scaling Web Applications7 Stages of Scaling Web Applications
7 Stages of Scaling Web Applications
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Better Software—Faster: Ten Best Practices from Sequoia's Microservices Summit
Better Software—Faster: Ten Best Practices from Sequoia's Microservices SummitBetter Software—Faster: Ten Best Practices from Sequoia's Microservices Summit
Better Software—Faster: Ten Best Practices from Sequoia's Microservices Summit
 

Similar to Node js mongodriver

Dpilot - Source Code with Snapshots
Dpilot - Source Code with SnapshotsDpilot - Source Code with Snapshots
Dpilot - Source Code with SnapshotsKritika Phulli
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - GuilinJackson Tian
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryAlexandre Morgaut
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScriptkvangork
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascriptkvangork
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Oliver Gierke
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applicationsjeromevdl
 
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
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 

Similar to Node js mongodriver (20)

Dpilot - Source Code with Snapshots
Dpilot - Source Code with SnapshotsDpilot - Source Code with Snapshots
Dpilot - Source Code with Snapshots
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love Story
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applications
 
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
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Ajax - a quick introduction
Ajax - a quick introductionAjax - a quick introduction
Ajax - a quick introduction
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 

More from christkv

From SQL to MongoDB
From SQL to MongoDBFrom SQL to MongoDB
From SQL to MongoDBchristkv
 
New in MongoDB 2.6
New in MongoDB 2.6New in MongoDB 2.6
New in MongoDB 2.6christkv
 
Lessons from 4 years of driver develoment
Lessons from 4 years of driver develomentLessons from 4 years of driver develoment
Lessons from 4 years of driver develomentchristkv
 
Storage talk
Storage talkStorage talk
Storage talkchristkv
 
Mongo db ecommerce
Mongo db ecommerceMongo db ecommerce
Mongo db ecommercechristkv
 
Cdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupCdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupchristkv
 
Mongodb intro
Mongodb introMongodb intro
Mongodb introchristkv
 
Schema design
Schema designSchema design
Schema designchristkv
 
Node.js and ruby
Node.js and rubyNode.js and ruby
Node.js and rubychristkv
 

More from christkv (9)

From SQL to MongoDB
From SQL to MongoDBFrom SQL to MongoDB
From SQL to MongoDB
 
New in MongoDB 2.6
New in MongoDB 2.6New in MongoDB 2.6
New in MongoDB 2.6
 
Lessons from 4 years of driver develoment
Lessons from 4 years of driver develomentLessons from 4 years of driver develoment
Lessons from 4 years of driver develoment
 
Storage talk
Storage talkStorage talk
Storage talk
 
Mongo db ecommerce
Mongo db ecommerceMongo db ecommerce
Mongo db ecommerce
 
Cdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetupCdr stats-vo ip-analytics_solution_mongodb_meetup
Cdr stats-vo ip-analytics_solution_mongodb_meetup
 
Mongodb intro
Mongodb introMongodb intro
Mongodb intro
 
Schema design
Schema designSchema design
Schema design
 
Node.js and ruby
Node.js and rubyNode.js and ruby
Node.js and ruby
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
🐬 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
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
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
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
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
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
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
 
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
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Recently uploaded (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
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
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
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...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
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
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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
 
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
 
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 ...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

Node js mongodriver

  • 1. An introduction to the node.js mongo driver Christian Amor Kvalheim
  • 2. • Asynchronous Javascript platform built on top of V8 • Single-threaded • Package manager • Awesome
  • 3. Hello World Server var http = require('http'); http.createServer( function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(8124, "127.0.0.1");
  • 4. Hello World Server Load the http library var http = require('http'); http.createServer( function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(8124, "127.0.0.1");
  • 5. Hello World Server Load the http library var http = require('http'); Set up the connection http.createServer( handler function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(8124, "127.0.0.1");
  • 6. How to get started • Install node.js (from source or package) • Install npm (node package manager) • Create an empty directory • npm install mongodb • npm install express
  • 7. Let’s do some code • Using Express and Mongo • Textmate basic.js
  • 8. Picking it apart var db = new Db('node-mongo-examples', new Server(host, port, {}), {native_parser:false}); db.open(function(err, db) { ... ..... app.listen(8124); var app = express.createServer(); app.get('/', function(req, res){ res.send('Hello World'); });
  • 9. Picking it apart Creates a db using the js bson parser var db = new Db('node-mongo-examples', new Server(host, port, {}), {native_parser:false}); db.open(function(err, db) { ... ..... app.listen(8124); var app = express.createServer(); app.get('/', function(req, res){ res.send('Hello World'); });
  • 10. Picking it apart Creates a db using the js bson parser var db = new Db('node-mongo-examples', new Server(host, port, {}), {native_parser:false}); Opens the connection to the db db.open(function(err, db) { ... ..... app.listen(8124); var app = express.createServer(); app.get('/', function(req, res){ res.send('Hello World'); });
  • 11. Picking it apart Creates a db using the js bson parser var db = new Db('node-mongo-examples', new Server(host, port, {}), {native_parser:false}); Opens the connection to the db db.open(function(err, db) { ... ..... app.listen(8124); The server is now running with access to the mongo server connection var app = express.createServer(); app.get('/', function(req, res){ res.send('Hello World'); });
  • 12. Let’s add some meat • CRUD operations • Textmate basic_2.js
  • 13. Picking it apart // Create method app.post('/location', function(req, res) { geoCodeDecorateObject(req.body.address, {description:req.body.description}, function(err, object) { db.collection('locations', function(err, collection) { // Insert doc collection.insert(object, {safe:true}, function(err, result) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_2.jade', {locals: {locations:items}}); }) }); }); }); });
  • 14. Picking it apart Geo Encode Address // Create method app.post('/location', function(req, res) { geoCodeDecorateObject(req.body.address, {description:req.body.description}, function(err, object) { db.collection('locations', function(err, collection) { // Insert doc collection.insert(object, {safe:true}, function(err, result) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_2.jade', {locals: {locations:items}}); }) }); }); }); });
  • 15. Picking it apart Geo Encode Address // Create method app.post('/location', function(req, res) { geoCodeDecorateObject(req.body.address, {description:req.body.description}, function(err, object) { db.collection('locations', function(err, collection) { // Insert doc collection.insert(object, {safe:true}, function(err, result) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_2.jade', {locals: {locations:items}}); }) Insert record, safe ensures that we trap any }); }); }); errors by doing a error check against }); mongodb
  • 16. Picking it apart // Create method app.post('/location', function(req, res) { geoCodeDecorateObject(req.body.address, {description:req.body.description}, function(err, object) { db.collection('locations', function(err, collection) { // Insert doc collection.insert(object, {safe:true}, function(err, result) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_2.jade', {locals: {locations:items}}); }) }); }); }); find all records from the locations }); collection. Find returns a cursor that allows for stepping through doucments
  • 17. Safe or not • Mongo Insert/Update/Delete are async • 2nd call to lastError required to check for the success of the operation • safe option ensures the second error call • you can also run the driver in strict mode
  • 18. Let’s add some meat • CRUD operations • Textmate basic_3.js
  • 19. Picking it apart // Delete method app.del('/location', function(req, res) { var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_3.jade', {locals: {locations:items}}); }) }) }); });
  • 20. Picking it apart Convert hex string to // Delete method objectID app.del('/location', function(req, res) { var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_3.jade', {locals: {locations:items}}); }) }) }); });
  • 21. Picking it apart Convert hex string to // Delete method objectID app.del('/location', function(req, res) { var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.remove({_id:id}, {safe:true}, function(err, numberOfDeletedRecords) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_3.jade', {locals: {locations:items}}); }) }) Remove the document using the specific id }); }); passed in, using safe.
  • 22. Let’s add some meat • CRUD operations • Textmate basic_4.js
  • 23. Picking it apart // Get method app.get('/location', function(req, res) { var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, item) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_4.jade', {locals: {locations:items, location:item}}); }) }) }); });
  • 24. Picking it apart Convert hex string to // Get method app.get('/location', function(req, res) { objectID var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, item) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_4.jade', {locals: {locations:items, location:item}}); }) }) }); });
  • 25. Picking it apart Convert hex string to // Get method app.get('/location', function(req, res) { objectID var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, item) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_4.jade', {locals: {locations:items, location:item}}); }) }) Locate one document by id }); });
  • 26. Let’s add some meat • CRUD operations • Textmate basic_5.js
  • 27. Picking it apart // Update method app.put('/location', function(req, res) { var id = ObjectID.createFromHexString(req.body.id); db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, object) { object.description = req.body.description; object.address = req.body.address; geoCodeDecorateObject(req.body.address, object, function(err, object) { collection.update({_id:object._id}, object, {safe:true}, function(err, numberOfUpdatedObjects) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_5.jade', {locals: {locations:items}}); }) }) })
  • 28. Picking it apart // Update method app.put('/location', function(req, res) { Locate object we wish var id = ObjectID.createFromHexString(req.body.id); to modify db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, object) { object.description = req.body.description; object.address = req.body.address; geoCodeDecorateObject(req.body.address, object, function(err, object) { collection.update({_id:object._id}, object, {safe:true}, function(err, numberOfUpdatedObjects) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_5.jade', {locals: {locations:items}}); }) }) })
  • 29. Picking it apart // Update method app.put('/location', function(req, res) { Locate object we wish var id = ObjectID.createFromHexString(req.body.id); to modify db.collection('locations', function(err, collection) { collection.findOne({_id:id}, function(err, object) { object.description = req.body.description; object.address = req.body.address; geoCodeDecorateObject(req.body.address, object, function(err, object) { collection.update({_id:object._id}, object, {safe:true}, function(err, numberOfUpdatedObjects) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_5.jade', {locals: {locations:items}}); }) }) }) Update document using the id to select what document to update
  • 30. Let’s add some meat • Final with search • Textmate basic_6.js
  • 31. Picking it apart db.open(function(err, db) { if(err) throw err // !!! CHANGE db.ensureIndex("locations", {loc:"2d"}, function(err, result) { if(err) throw err app.listen(8124); }) });
  • 32. Picking it apart db.open(function(err, db) { if(err) throw err // !!! CHANGE db.ensureIndex("locations", {loc:"2d"}, function(err, result) { if(err) throw err app.listen(8124); }) }); Ensures there is a 2d geospatial index on the attribute loc on any document in the locations collection
  • 33. Picking it apart var geoCodeDecorateObject = function(address, object, callback) { var googleGeoCodeApi = {host: 'maps.googleapis.com', port: 80,path: '/maps/api/geocode/json?sensor=false&address=' + escape(address), method: 'GET' }; var clientReq = http.get(googleGeoCodeApi, function(clientRes) { var data = []; clientRes.on('data', function(chunk) { data.push(chunk.toString()); }); clientRes.on('end', function() { var googleObject = JSON.parse(data.join('')); object.address = address; object.geodata = googleObject.results.pop(); // !!! CHANGE object.loc = {long:object.geodata.geometry.location.lng, lat:object.geodata.geometry.location.lat}; callback(null, object); });
  • 34. Picking it apart var geoCodeDecorateObject = function(address, object, callback) { var googleGeoCodeApi = {host: 'maps.googleapis.com', port: 80,path: '/maps/api/geocode/json?sensor=false&address=' + escape(address), method: 'GET' }; var clientReq = http.get(googleGeoCodeApi, function(clientRes) { var data = []; clientRes.on('data', function(chunk) { data.push(chunk.toString()); We are adding a loc }); clientRes.on('end', function() { attribute to all var googleObject = JSON.parse(data.join('')); documents with object.address = address; object.geodata = googleObject.results.pop(); longtidude and // !!! CHANGE latitude in the right object.loc = {long:object.geodata.geometry.location.lng, lat:object.geodata.geometry.location.lat}; order for mongodb to callback(null, object); }); search
  • 35. Picking it apart // !!! CHANGE // Search option app.post('/search', function(req, res) { geoCodeDecorateObject(req.body.address, {}, function(err, object) { // Unpack geo object var long = object.geodata.geometry.location.lng; var lat = object.geodata.geometry.location.lat db.collection('locations', function(err, collection) { collection.find({loc : {'$near': [long, lat], '$maxDistance': parseFloat(req.body.distance)}}).toArray(function(err, geoItems) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_6.jade', {locals: {locations:items, results:geoItems}}); }) }); }); }); });
  • 36. Picking it apart Encode address for // !!! CHANGE // Search option searching app.post('/search', function(req, res) { geoCodeDecorateObject(req.body.address, {}, function(err, object) { // Unpack geo object var long = object.geodata.geometry.location.lng; var lat = object.geodata.geometry.location.lat db.collection('locations', function(err, collection) { collection.find({loc : {'$near': [long, lat], '$maxDistance': parseFloat(req.body.distance)}}).toArray(function(err, geoItems) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_6.jade', {locals: {locations:items, results:geoItems}}); }) }); }); }); });
  • 37. Picking it apart Encode address for // !!! CHANGE // Search option searching app.post('/search', function(req, res) { geoCodeDecorateObject(req.body.address, {}, function(err, object) { // Unpack geo object var long = object.geodata.geometry.location.lng; var lat = object.geodata.geometry.location.lat db.collection('locations', function(err, collection) { collection.find({loc : {'$near': [long, lat], '$maxDistance': parseFloat(req.body.distance)}}).toArray(function(err, geoItems) { // Fetch all docs for rendering of list collection.find({}).toArray(function(err, items) { res.render('./basic_6.jade', {locals: {locations:items, results:geoItems}}); }) }); Search for all items $near our address at }); }); $maxDistance });
  • 38. Other features • Cursors • Grid FS
  • 39. Cursors • toArray Function • each Function • streamRecords Function
  • 40. toArray collection.find().toArray(function(err, documents){ test.deepEqual([1, 2, 3], documents[0].b); // Let's close the db test.done(); });
  • 41. toArray Fetches all docs in one go for the query. Use with caution collection.find().toArray(function(err, documents){ test.deepEqual([1, 2, 3], documents[0].b); // Let's close the db test.done(); });
  • 42. each collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){ if(item != null) { // Do work } else { // Finished } });
  • 43. each Fetches docs in batches and allows iteration over results collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){ if(item != null) { // Do work } else { // Finished } });
  • 44. each Fetches docs in batches and allows iteration over results collection.find({}, {'sort':[['age', 1]]}).each(function(err, item){ if(item != null) { // Do work } else { // Finished } }); Returns null when no more results available
  • 45. streamRecords var stream = collection.find({}, {'limit' : 3}).streamRecords(); stream.on('end', function() { // No more results in the pipe }); stream.on('data',function(data){ // Item });
  • 46. streamRecords var stream = collection.find({}, {'limit' : 3}).streamRecords(); stream.on('end', function() { // No more results in the pipe }); stream.on('data',function(data){ // Item }); When an item is ready the event ‘data’ is triggered
  • 47. streamRecords var stream = collection.find({}, {'limit' : 3}).streamRecords(); When no more items stream.on('end', function() { are available // No more results in the pipe }); stream.on('data',function(data){ // Item }); When an item is ready the event ‘data’ is triggered
  • 48. streamRecords var stream = collection.find({}, {'limit' : 3}).streamRecords(); When no more items stream.on('end', function() { are available // No more results in the pipe }); REFERED P stream.on('data',function(data){ // Item }); When an item is ready the event ‘data’ is triggered
  • 49. Grid FS • Write and read a file • Stream a file
  • 50. Write a file var gridStore = new GridStore(client, 'test_gs_writing_file', 'w'); gridStore.open(function(err, gridStore) { gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) { GridStore.read(client, 'test_gs_writing_file', function(err, fileData) { });
  • 51. Write a file var gridStore = new GridStore(client, 'test_gs_writing_file', 'w'); gridStore.open(function(err, gridStore) { gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) { Writes the file in chunks to mongodb (avoids freezing the eventloop in node.js) GridStore.read(client, 'test_gs_writing_file', function(err, fileData) { });
  • 52. Write a file var gridStore = new GridStore(client, 'test_gs_writing_file', 'w'); gridStore.open(function(err, gridStore) { gridStore.writeFile('./test_gs_weird_bug.png', function(err, gridStore) { Writes the file in chunks to mongodb (avoids freezing the eventloop in node.js) GridStore.read(client, 'test_gs_writing_file', function(err, fileData) { }); Read the whole file. Careful with the memory
  • 53. Stream a file var gridStore = new GridStore(client, "test_gs_read_stream", "r"); gridStore.open(function(err, gs) { var stream = gs.stream(true); stream.on("data", function(chunk) { // Received a chunk of data }); stream.on("end", function() { // Finished streaming }); });
  • 54. Stream a file var gridStore = new GridStore(client, "test_gs_read_stream", "r"); gridStore.open(function(err, gs) { var stream = gs.stream(true); Receive a chunk and do something stream.on("data", function(chunk) { // Received a chunk of data }); stream.on("end", function() { // Finished streaming }); });
  • 55. Stream a file var gridStore = new GridStore(client, "test_gs_read_stream", "r"); gridStore.open(function(err, gs) { var stream = gs.stream(true); Receive a chunk and do something stream.on("data", function(chunk) { // Received a chunk of data }); Finshed stream the file stream.on("end", function() { // Finished streaming }); });
  • 56. Stream a file var gridStore = new GridStore(client, "test_gs_read_stream", "r"); gridStore.open(function(err, gs) { var stream = gs.stream(true); Receive a chunk and do something stream.on("data", function(chunk) { // Received a chunk of data }); Finshed stream the file stream.on("end", function() { // Finished streaming PR EFE RED }); });
  • 57. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}); } collection.count(function(err, count) { // count is > 0 <= 100 });
  • 58. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}); } All executed in parallel, non- deterministic end of execution collection.count(function(err, count) { // count is > 0 <= 100 });
  • 59. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}); } All executed in parallel, non- deterministic end of execution collection.count(function(err, count) { // count is > 0 <= 100 }); All inserts MAY have been written to disk so passes most of the time. But with Pooling NO WAY
  • 60. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, function(err, result) { // Do something }); } ?????????????????????????????? collection.count(function(err, count) { // count is > 0 <= 100 });
  • 61. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, function(err, result) { // Do something }); } How do we handle the callbacks ?????????????????????????????? collection.count(function(err, count) { // count is > 0 <= 100 });
  • 62. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, function(err, result) { // Do something }); } How do we handle the callbacks ?????????????????????????????? collection.count(function(err, count) { // count is > 0 <= 100 }); How do we get to this code ??????
  • 63. Typical starting problems for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, function(err, result) { // Do something }); } How do we handle the callbacks ?????????????????????????????? collection.count(function(err, count) { // count is > 0 <= 100 }); How do we get to this code ?????? Many possible solutions
  • 64. My Choosen Solution https://github.com/creationix/step Step( function insert() { var group = this.group(); for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, group()); } }, function finished() { collection.count(function(err, count) { // Count is 100 :) }); } )
  • 65. My Choosen Solution https://github.com/creationix/step Step( function insert() { var group = this.group(); for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, group()); } }, Ensures all the inserts are finished before calling the next function function finished() { collection.count(function(err, count) { // Count is 100 :) }); } )
  • 66. My Choosen Solution https://github.com/creationix/step Step( function insert() { var group = this.group(); for(var i = 0; i < 100; i++) { collection.insert({'i':i}, {safe:true}, group()); } }, Ensures all the inserts are finished before calling the next function function finished() { collection.count(function(err, count) { // Count is 100 :) }); } ) When all inserts are done :)
  • 67. DONE Code on https://github.com/christkv/mongodb-hamburg

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n