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
57
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
260
ForwardJS - RethinkDB - Getting Started
thejsj
0
200
ForwardJS - RethinkDB - Advanced Queries
thejsj
1
200
Automatic Failover in RethinkDB
thejsj
0
220
Workshop: Introduction to RethinkDB : Santa Cruz JS
thejsj
1
120
Push databases: A better way to build realtime apps
thejsj
0
130
Data Modeling in RethinkDB
thejsj
4
270
RethinkDB+Angular.js: Building realtime web applications
thejsj
10
30k
Introduction to RethinkDB: 1KE Meetup
thejsj
0
50
Other Decks in Programming
See All in Programming
ZeroETLで始めるDynamoDBとS3の連携
afooooil
0
150
中級グラフィックス入門~効率的なメッシュレット描画~
projectasura
4
2.5k
実践 Dev Containers × Claude Code
touyu
1
160
構文解析器入門
ydah
7
2k
MCP連携で加速するAI駆動開発/mcp integration accelerates ai-driven-development
bpstudy
0
280
Terraform やるなら公式スタイルガイドを読もう 〜重要項目 10選〜
hiyanger
12
2.9k
WebAssemblyインタプリタを書く ~Component Modelを添えて~
ruccho
1
650
Claude Code で Astro blog を Pages から Workers へ移行してみた
codehex
0
180
AIのメモリー
watany
13
1.3k
可変性を制する設計: 構造と振る舞いから考える概念モデリングとその実装
a_suenami
10
1.7k
なぜ今、Terraformの本を書いたのか? - 著者陣に聞く!『Terraformではじめる実践IaC』登壇資料
fufuhu
4
500
それ CLI フレームワークがなくてもできるよ / Building CLI Tools Without Frameworks
orgachem
PRO
17
3.7k
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Making the Leap to Tech Lead
cromwellryan
134
9.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
47
9.6k
Building Adaptive Systems
keathley
43
2.7k
Music & Morning Musume
bryan
46
6.7k
Writing Fast Ruby
sferik
628
62k
It's Worth the Effort
3n
185
28k
Gamification - CAS2011
davidbonilla
81
5.4k
Code Review Best Practice
trishagee
69
19k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
A better future with KSS
kneath
239
17k
Automating Front-end Workflow
addyosmani
1370
200k
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/