Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Introduction to RethinkDB : DevMountain
Search
Jorge Silva
May 09, 2015
Programming
0
51
Introduction to RethinkDB : DevMountain
Workshop given at Dev Mountain on May 6th, 2015.
Jorge Silva
May 09, 2015
Tweet
Share
More Decks by Jorge Silva
See All by Jorge Silva
Introduction to RethinkDB : Move fast and break things
thejsj
2
250
ForwardJS - RethinkDB - Getting Started
thejsj
0
180
ForwardJS - RethinkDB - Advanced Queries
thejsj
1
180
Automatic Failover in RethinkDB
thejsj
0
220
Workshop: Introduction to RethinkDB : Santa Cruz JS
thejsj
1
110
Push databases: A better way to build realtime apps
thejsj
0
120
Data Modeling in RethinkDB
thejsj
4
260
RethinkDB+Angular.js: Building realtime web applications
thejsj
10
30k
Introduction to RethinkDB: 1KE Meetup
thejsj
0
41
Other Decks in Programming
See All in Programming
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
120
Jakarta EE meets AI
ivargrimstad
0
270
RubyLSPのマルチバイト文字対応
notfounds
0
120
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
cmp.Or に感動した
otakakot
3
230
初めてDefinitelyTypedにPRを出した話
syumai
0
420
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
480
.NET のための通信フレームワーク MagicOnion 入門 / Introduction to MagicOnion
mayuki
1
1.8k
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
ヤプリ新卒SREの オンボーディング
masaki12
0
130
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
350
Why Jakarta EE Matters to Spring - and Vice Versa
ivargrimstad
0
1.2k
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1366
200k
The Cult of Friendly URLs
andyhume
78
6k
Agile that works and the tools we love
rasmusluckow
327
21k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
How to Ace a Technical Interview
jacobian
276
23k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
900
Building a Scalable Design System with Sketch
lauravandoore
459
33k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Intergalactic Javascript Robots from Outer Space
tanoku
269
27k
Site-Speed That Sticks
csswizardry
0
33
Transcript
RethinkDB The database for the realtime web DevMountain Provo, Utah
May 6, 2015
Jorge Silva @thejsj Developer Evangelist @ RethinkDB
Introduction What is RethinkDB?
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
Built for Realtime Apps • Subscribe to change notifications from
database queries • No more polling — the database pushes changes to your app • Reduce the amount of plumbing needed to stream live updates
RethinkDB Structure Database → Table → Document MySQL: Database →
Table → Row MongoDB: Database → Collection → Document
Sample Document { "name": "Will Riker", "position": "Commander", "height": 193,
"birthdate": Mon Aug 19 2335, "ships": [ { "name": "USS Pegasus" }, { "name": "USS Potemkin" }, { "name": "USS Enterprise" }, ], ... }
Installing RethinkDB http://rethinkdb.com/install/
http://rethinkdb-chat.thejsj.com:10001/ #dataexplorer http://bit.ly/1zMCJH2 Having Issues?
Introduction to ReQL RethinkDB Query Language
Introduction to ReQL • ReQL embeds natively into your programming
language • Compose ReQL queries by chaining commands
Anatomy of a ReQL Query r.table("users") .pluck("last_name") .distinct().count() Number of
unique last names
Anatomy of a ReQL Query r.table("users") .pluck("last_name") .distinct().count() Access a
database table
Anatomy of a ReQL Query r.table("users") .pluck("last_name") .distinct().count() Isolate a
document property
Anatomy of a ReQL Query r.table("users") .pluck("last_name") .distinct().count() Consolidate duplicate
values
Anatomy of a ReQL Query r.table("users") .pluck("last_name") .distinct().count() Display the
number of items
Sample ReQL Queries r.table("users") .filter(r.row("age").gt(30)) r.table("users") .pluck("last_name") .distinct().count() r.table("fellowship") .filter({species:
"hobbit"}) .update({species: "halfling"})
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
Running Queries http://bit.ly/1JQ8imw
Secondary Indexes • Queries performed against indexes are much faster
• Can index on a single property, multiple fields, or arbitrary ReQL expressions
Querying an Index r.table("fellowship") .indexCreate("species") r.table("fellowship") .getAll("human", {index: "species"}) Find
all humans in “fellowship”
Running Queries: Indexes
Anonymous Functions r.range(5).map(function(i) { return i.mul(2); }) Multiply each value
by 2 You can pass anonymous functions to commands like map and reduce:
The r.row command Multiply each value by 2 You can
often use r.row instead of an anonymous function: r.range(5).map(r.row.mul(2))
Running Queries: Functions
Query Composition • ReQL embeds natively in your programming language
• Pass around ReQL expressions like any other code • You can assign ReQL expressions to variables or store them in functions
Running Queries: Query Composition
Understanding ReQL • Anonymous function must return a valid ReQL
expression • Client driver translates ReQL queries into wire protocol • In JS use e.g. the mul and gt commands instead of the normal operators
Additional ReQL Features • Geospatial indexing for location- based queries
• Date and time functions for time data • Support for storing binary objects
Realtime Updates Working with Changefeeds
Subscribe to change notifications on database queries Changefeeds
r.table("users").changes() Track changes on the users table Changefeeds
Changefeeds • The changes command returns a cursor that receives
updates • Each update includes the new and old value of the modified record
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 }
Changefeeds r.table("users").changes() r.table("users") .filter({name: "Bob"}).delete() Changefeed output: { new_val: null,
old_val: { id: '362ae837-2e29-4695-adef-4fa415138f90', name: 'Bob', ... } }
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' } }
Changefeeds r.table("players") .orderBy({index: r.desc("score")}) .limit(3).changes() Track top three players by
score Chain the changes command to an actual ReQL query:
Changefeeds r.table("table").get(ID).changes() r.table("table").getAll(ID).changes() r.table("table").between(X, Y).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:
Using Changefeeds
Building Web Apps Using RethinkDB in Node
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
> Client Driver Install the JS client driver from NPM
in your Node.js project: $ npm install rethinkdb --save
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() { // Documented inserted }); Add Bob to the “users” table
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
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
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
Client Driver var r = require("rethinkdb"); r.connect().then(function(conn) { return r.table("users")
.insert({name: “Bob”}) .run(conn, function (err, output) { console.log(output); }) }) Run the query on a connection
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
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
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
Using Changefeeds r.connect().then(function(conn) { return r.table("fellowship") .changes().run(conn, function (err, cursor)
{ cursor.each(function(err, item) { console.log(item); }); }); Attach a changefeed to the table
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); }); }); Iterate over every value passed into the cursor
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
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
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
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
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
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
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
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
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
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
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
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
Tutorial: Building a chat app
#1: Clone the repository git clone
[email protected]
:thejsj/ rethinkdb-workshp.git or https://github.com/thejsj/rethinkdb-
workshop/tarball/master or http://bit.ly/1cmsO0B
#2: Create database and tables (PUPZPVSEBUBFYQMPSFSBOESVO UIFGPMMPXJOHRVFSJFT r.dbCreate(‘chat’); r.db(‘chat’).tableCreate(‘messages’); r.db(‘chat’).tableCreate(‘users’,
{ primaryKey: ‘email’ });
#3: Insert sample data (PUPZPVSEBUBFYQMPSFSBOESVOUIF GPMMPXJOHRVFSZ r.table(‘messages’) .insert(r.json( r.http(‘http://bit.ly/1zMGw7b') ))
r.table(‘users’) .insert(r.json( r.http(‘http://bit.ly/1zBj4tm') ))
#4: Go to server/index.js -PPLGPSUIFDPNNFOUTJOPSEFS UPXSJUFUIFDPSSFDU3F2-RVFSJFT // Step 1 //
Write a query…
Connections *OUIJTBQQ UIFrPCKFDUDPOUBJOT BDPOOFDUJPO r.table(‘messages’).run(r.conn);
Suggestions "EEJOHSPPNTUPDIBUBQQ "EEJOHVTFSTJOSPPNDIBU "EENVMUJQMFOPEFTUPDMVTUFS "EENFTTBHFTFBSDI
"EENFTTBHFMJLJOH 4VQQPSUEFMFUJOHNFTTBHFT 4DIFNBTEFOFEJO3&"%.&
#5: Switch database $POOFDUUPUIFGPMMPXJOH EBUBCBTF TPXFDBOBMMTIBSF NFTTBHFT { host :
‘http://', port : 28015, db : ‘chat’ }
Additional Resources • RethinkDB website: http://rethinkdb.com • RethinkDB cookbook: http://rethinkdb.com/docs/cookbook
• RethinkDB installation: http://rethinkdb.com/docs/install/