Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Workshop: Introduction to RethinkDB : Santa Cru...

Workshop: Introduction to RethinkDB : Santa Cruz JS

Jorge Silva

July 09, 2015
Tweet

More Decks by Jorge Silva

Other Decks in Programming

Transcript

  1. RethinkDB The database for the realtime web Santa Cruz JS

    Santa Cruz, California July 9, 2015
  2. Schedule 1. What is RethinkDB? 2. RethinkDB query language 3.

    Working with changefeeds 4. Using RethinkDB with Node.js 5. Tutorial: Building a chat app
  3. What is RethinkDB? • Open source database for building realtime

    web applications • NoSQL database that stores schemaless JSON documents • Distributed database that is easy to scale
  4. Built for Realtime Apps • Subscribe to change notifications from

    database queries (changefeeds) • No more polling — the database pushes changes to your app • Reduce the amount of plumbing needed to stream live updates
  5. Built for Realtime Apps • Having your database push changes

    keeps your database as the central source of truth • Having a central source of truth simplifies your architecture
  6. Power and Convenience • Highly expressive query language • Relational

    features like table joins • Powerful admin UI with point- and-click cluster management
  7. RethinkDB Structure Database → Table → Document MySQL: Database →

    Table → Row MongoDB: Database → Collection → Document
  8. Sample Document { "name": "Will Riker", "position": "Commander", "height": 193,

    "birthdate": Mon Aug 19 2335, "ships": [ { "name": "USS Pegasus" }, { "name": "USS Potemkin" }, { "name": "USS Enterprise" }, ], ... }
  9. Differences with Firebase • Firebase is a cloud service, not

    an open-source database • Because Firebase is not a database, it has limited querying abilities • Firebase is made to be queried from the browser
  10. Differences with MongoDB • RethinkDB supports joins and subqueries •

    MongoDB only supports the traditional query-response model. You can't subscribe to queries.
  11. Introduction to ReQL • ReQL embeds natively into your programming

    language • Compose ReQL queries by chaining commands
  12. ReQL Commands • Transformations: map, orderBy, skip, limit, slice •

    Aggregations: group, reduce, count, sum, avg, min, max, distinct, contains • Documents: row, pluck, without, merge, append, difference, keys, hasFields, spliceAt • Writing: insert, update, replace, delete • Control: forEach, range, branch, do, coerceTo, expr
  13. ReQL Commands • Transformations: map, orderBy, skip, limit, slice •

    Aggregations: group, reduce, count, sum, avg, min, max, distinct, contains • Documents: row, pluck, without, merge, append, difference, keys, hasFields, spliceAt • Writing: insert, update, replace, delete • Control: forEach, range, branch, do, coerceTo, expr
  14. ReQL Commands • Transformations: map, orderBy, skip, limit, slice •

    Aggregations: group, reduce, count, sum, avg, min, max, distinct, contains • Documents: row, pluck, without, merge, append, difference, keys, hasFields, spliceAt • Writing: insert, update, replace, delete • Control: forEach, range, branch, do, coerceTo, expr
  15. ReQL Commands • Transformations: map, orderBy, skip, limit, slice •

    Aggregations: group, reduce, count, sum, avg, min, max, distinct, contains • Documents: row, pluck, without, merge, append, difference, keys, hasFields, spliceAt • Writing: insert, update, replace, delete • Control: forEach, range, branch, do, coerceTo, expr
  16. ReQL Commands • Transformations: map, orderBy, skip, limit, slice •

    Aggregations: group, reduce, count, sum, avg, min, max, distinct, contains • Documents: row, pluck, without, merge, append, difference, keys, hasFields, spliceAt • Writing: insert, update, replace, delete • Control: forEach, range, branch, do, coerceTo, expr
  17. Understanding ReQL • All queries are executed by the database,

    not the client • Client driver translates ReQL queries into wire protocol • In JS use e.g. the mul and gt commands instead of the normal operators
  18. Additional ReQL Features • Geospatial indexing for location- based queries

    • Date and time functions • Support for storing binary objects • Execute http requests using r.http
  19. Changefeeds • The changes command returns a cursor that receives

    updates • Each update includes the new and old value of the modified record
  20. Changefeeds r.table("users").changes() r.table("users") .insert({name: "Bob"}) Changefeed output: { new_val: {

    id: '362ae837-2e29-4695-adef-4fa415138f90', name: 'Bob', ... }, old_val: null }
  21. Changefeeds r.table("users").changes() r.table("users") .get("362ae837-2e29-4695-adef-4fa415138f90") .update({name: "Bobbby"}) Changefeed output: { new_val:

    { id: '362ae837-2e29-4695-adef-4fa415138f90', name: 'Bobby' }, old_val: { id: '362ae837-2e29-4695-adef-4fa415138f90', name: 'Bob' } }
  22. Changefeeds r.table("table").get(ID).changes() r.table("table").getAll(ID).changes() r.table("table").between(X, Y).changes() r.table("table").pluck(X, Y, Z).changes() r.table("table").filter(CONDITION).changes() r.table("table").union(ID).changes()

    r.table("table").map(FUNCTION).changes() r.table("table").min(INDEX).changes() r.table("table").max(INDEX).changes() r.table("table").orderBy(INDEX) .limit(N).changes() Commands that currently work with changefeeds:
  23. Client Driver • Use a RethinkDB client driver to access

    the database in your app • Official drivers available for Ruby, Python, and JavaScript • Third-party drivers available for other languages like Go and Clojure
  24. > Client Driver Install the JS client driver from npm

    in your Node.js project: $ npm install rethinkdb --save
  25. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob”}).run(conn) .finally(function () { conn.close(); }); }).then(function() { // Document inserted }); Add Bob to the “users” table
  26. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob"}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }); Import the RethinkDB module
  27. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob”}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }); Connect to the database
  28. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob”}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }); ReQL query that inserts a record
  29. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob”}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }); Run the query on a connection
  30. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob"}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }); Display query response
  31. Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")

    .insert({name: “Bob"}).run(conn) .finally(function () { conn.close(); }); }).then(function(output) { console.log(output); }).error(function(err) { console.log("Failed:", err); }); Handle errors emitted by Promise
  32. Using Changefeeds r.connect().then(function(conn) { return r.table("fellowship") .changes().run(conn); }) .then(function(cursor) {

    cursor.each(function(err, item) { console.log(item); }); }); Display every change on the “fellowship” table
  33. Using Changefeeds Attach a changefeed to the table r.connect().then(function(conn) {

    return r.table("fellowship") .changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, item) { console.log(item); }); });
  34. Using Changefeeds Iterate over every value passed into the cursor

    r.connect().then(function(conn) { return r.table("fellowship") .changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, item) { console.log(item); }); });
  35. Using Changefeeds r.connect().then(function(conn) { return r.table("fellowship") .changes().run(conn); }) .then(function(cursor) {

    cursor.each(function(err, item) { console.log(item); }); }); Display received changes in the console
  36. Using Socket.io • Powerful framework for realtime client/server communication •

    Supports WebSockets, long polling, and other transports • Lets you send JSON messages between your app and frontend
  37. Socket.io (Server) var sockio = require("socket.io"); var app = require("express")();

    var r = require("rethinkdb"); var io = sockio.listen(app.listen(8090)); r.connect().then(function(conn) { return r.table("players") .orderBy({index: r.desc("score")}) .limit(5).changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, data) { io.sockets.emit("update", data); }); }); Broadcast score changes over Socket.io
  38. Socket.io (Server) var sockio = require("socket.io"); var app = require("express")();

    var r = require("rethinkdb"); var io = sockio.listen(app.listen(8090)); r.connect().then(function(conn) { return r.table("players") .orderBy({index: r.desc("score")}) .limit(5).changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, data) { io.sockets.emit("update", data); }); }); Load the Socket.io module
  39. Socket.io (Server) var sockio = require("socket.io"); var app = require("express")();

    var r = require("rethinkdb"); var io = sockio.listen(app.listen(8090)); r.connect().then(function(conn) { return r.table("players") .orderBy({index: r.desc("score")}) .limit(5).changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, data) { io.sockets.emit("update", data); }); }); Instantiate Socket.io server
  40. Socket.io (Server) var sockio = require("socket.io"); var app = require("express")();

    var r = require("rethinkdb"); var io = sockio.listen(app.listen(8090)); r.connect().then(function(conn) { return r.table("players") .orderBy({index: r.desc("score")}) .limit(5).changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, data) { io.sockets.emit("update", data); }); }); Attach a changefeed to the query
  41. Socket.io (Server) var sockio = require("socket.io"); var app = require("express")();

    var r = require("rethinkdb"); var io = sockio.listen(app.listen(8090)); r.connect().then(function(conn) { return r.table("players") .orderBy({index: r.desc("score")}) .limit(5).changes().run(conn); }) .then(function(cursor) { cursor.each(function(err, data) { io.sockets.emit("update", data); }); }); Broadcast updates to all Socket.io connections
  42. Socket.io (Client) <html> <head> <title>Real-time web app</title> <script src="/socket.io/socket.io.js"></script> <script>

    var socket = io.connect(); socket.on("update", function(data) { console.log("Update:", data); }); Receive Socket.io updates on frontend
  43. Socket.io (Client) <html> <head> <title>Real-time web app</title> <script src="/socket.io/socket.io.js"></script> <script>

    var socket = io.connect(); socket.on("update", function(data) { console.log("Update:", data); }); Load the Socket.io client script
  44. Socket.io (Client) <html> <head> <title>Real-time web app</title> <script src="/socket.io/socket.io.js"></script> <script>

    var socket = io.connect(); socket.on("update", function(data) { console.log("Update:", data); }); Connect to the Socket.io server
  45. Socket.io (Client) <html> <head> <title>Real-time web app</title> <script src="/socket.io/socket.io.js"></script> <script>

    var socket = io.connect(); socket.on("update", function(data) { console.log("Update:", data); }); Create handler for “update” messages
  46. Socket.io (Client) <html> <head> <title>Real-time web app</title> <script src="/socket.io/socket.io.js"></script> <script>

    var socket = io.connect(); socket.on("update", function(data) { console.log("Update:", data); }); Display update in browser console
  47. #1: Clone the repository Clone From GitHub: git clone https://github.com/thejsj/

    rethinkdb-workshop.git Download Tarball: https://github.com/thejsj/rethinkdb- workshop/tarball/master
  48. #2: Install Dependencies // Go to the project directory cd

    rethinkdb-workshop // Install dependencies npm install
  49. #3: Go to config/default.js 6QEBUFZPVS3FUIJOL%#EBUBCBTF DPOHVSBUJPO var config = {

    "rethinkdb": { "host": "localhost", // or rethinkdb.thejsj.com "port": 29015, "db" : "rethinkdb_workshop" // or GITHUB_HANDLE_rethinkdb_workshop },
  50. #5: Switch database $POOFDUUPUIFGPMMPXJOHEBUBCBTF TPXF DBOBMMTIBSFNFTTBHFT var config = {

    "rethinkdb": { "host": "rethinkdb.thejsj.com", "port": 29015, "db" : "GITHUB_HANDLE_rethinkdb_workshop" },
  51. Next steps • Advanced Commands: `r.do`, `r.branch`, `r.forEach` • Map/Reduce

    queries • Indexes (multi, compound, index functions, geospatial) • Sharding and replication