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
120
Data Modeling in RethinkDB
thejsj
4
270
RethinkDB+Angular.js: Building realtime web applications
thejsj
10
30k
Introduction to RethinkDB: 1KE Meetup
thejsj
0
48
Other Decks in Programming
See All in Programming
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
830
脱Riverpod?fqueryで考える、TanStack Queryライクなアーキテクチャの可能性
ostk0069
0
320
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
5
1.4k
ソフトウェア品質を数字で捉える技術。事業成長を支えるシステム品質の マネジメント
takuya542
2
14k
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
660
オンコール⼊⾨〜ページャーが鳴る前に、あなたが備えられること〜 / Before The Pager Rings
yktakaha4
1
550
iOS 26にアップデートすると実機でのHot Reloadができない?
umigishiaoi
0
130
Startups on Rails in Past, Present and Future–Irina Nazarova, RailsConf 2025
irinanazarova
0
150
PipeCDのプラグイン化で目指すところ
warashi
1
290
VS Code Update for GitHub Copilot
74th
2
660
スタートアップの急成長を支えるプラットフォームエンジニアリングと組織戦略
sutochin26
1
6.5k
PHPで始める振る舞い駆動開発(Behaviour-Driven Development)
ohmori_yusuke
2
410
Featured
See All Featured
Statistics for Hackers
jakevdp
799
220k
Optimizing for Happiness
mojombo
379
70k
Building Adaptive Systems
keathley
43
2.7k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Producing Creativity
orderedlist
PRO
346
40k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Pragmatic Product Professional
lauravandoore
35
6.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
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/