
SQL and RethinkDB share very similar terminology. Below is a table of terms and concepts in the two systems.
| SQL | RethinkDB |
|---|---|
| database | database |
| table | table |
| row | document |
| column | field |
| table joins | table joins |
| primary key | primary key (by default id) |
| index | index |
This is a list of queries for inserting data into a database.
| SQL | ReQL |
|---|---|
INSERT INTO users(user_id,
age,
name)
VALUES ("f62255a8259f",
30,
Peter) | r.table("users").insert({
:user_id => "f62255a8259f",
:age => 30,
:name => "Peter"
}) |
This is a list of queries for selecting data out of a database.
| SQL | ReQL |
|---|---|
SELECT * FROM users |
r.table("users") |
SELECT user_id, name FROM users |
r.table("users")
.pluck("user_id", "name") |
SELECT * FROM users WHERE name = "Peter" |
r.table("users").filter({
:name => "Peter"
}) If you have a secondary index built on the field r.table("users")
.get_all("Peter", :index => "name") |
SELECT * FROM users WHERE name = "Peter" AND age = 30 |
r.table("users").filter({
:name => "Peter",
:age => 30
}) |
SELECT * FROM users WHERE name LIKE "P%" |
r.table("users").filter{ |row|
row['name'].match("^P")
} |
SELECT * FROM users ORDER BY name ASC |
r.table("users").order_by("name") |
SELECT * FROM users ORDER BY name DESC |
r.table("users").order_by(
r.desc("name")
) |
SELECT user_id FROM users WHERE name = "Peter" ORDER BY name DESC |
r.table("users").filter({
:name => "Peter"
}).order_by(
r.desc("name")
).pluck("user_id") |
SELECT * FROM users LIMIT 5 SKIP 10 |
r.table("users").skip(10).limit(5) |
SELECT * FROM users
WHERE name IN ('Peter', 'John') |
r.table("users").filter{ |doc|
r.expr(["Peter", "John"])
.contains(doc["name"])
} If you have a secondary index built on the field r.table("users")
.get_all("Peter", "John",
:index => "name") |
SELECT * FROM users
WHERE name NOT IN ('Peter', 'John') |
r.table("users").filter{ |doc|
r.expr(["Peter", "John"])
.contains(doc["name"])
.not()
} |
SELECT COUNT(*) FROM users |
r.table("users").count() |
SELECT COUNT(name) FROM users WHERE age > 18 |
r.table("users").filter{ |doc|
(doc.has_fields("name") & doc["age"] > 18)
}.count() |
SELECT AVG("age")
FROM users |
r.table("users")
.avg("age") |
SELECT MAX("age")
FROM users |
r.table("users")["age"]
.max() |
SELECT DISTINCT(name) FROM users |
r.table("users").pluck("name").distinct() |
SELECT *
FROM users
WHERE age BETWEEN 18 AND 65; |
r.table("users").filter{ |doc|
(doc["age"] >= 18) & (doc["age"] <= 65)
} If you have a secondary index built on the field age, you can run a more efficient query: r.table("users")
.between(18, 65, :index => "age") |
SELECT name, 'is_adult' = CASE
WHEN age>18 THEN 'yes'
ELSE 'no'
END
FROM users |
r.table("users").map{ |user|
{
:name => user["name"],
:is_adult => r.branch(
user["age"] > 18
"yes",
"no"
)
}
} |
SELECT *
FROM posts
WHERE EXISTS
(SELECT * FROM users
WHERE posts.author_id
= users.id) |
r.table("posts")
.filter{ |post|
r.table("users")
.filter{ |user|
user.id == post.author_id
}.count() > 0
} |
This is a list of commands for updating data in the database.
| SQL | ReQL |
|---|---|
UPDATE users
SET age = 18
WHERE age < 18 |
r.table("users").filter{ |doc|
doc["age"] < 18
}.update({
:age => 18
}) |
UPDATE users
SET age = age+1 |
r.table("users").update{ |doc|
{ :age => doc["age"]+1 }
} |
This is a list of queries for deleting data from the database.
| SQL | ReQL |
|---|---|
DELETE FROM users |
r.table("users").delete() |
DELETE FROM users WHERE age < 18 |
r.table("users").filter{ |doc|
doc["age"] < 18
}.delete() |
This is a list of queries for performing joins between multiple tables.
| SQL | ReQL |
|---|---|
SELECT * FROM posts JOIN users ON posts.user_id = users.id |
r.table("posts").inner_join(
r.table("users")
) { |post, user|
post["user_id"] == user["id"]
}.zip() Note: If you have an index (primary key or secondary index) built on the field of the right table, you can perform a more efficient join with eq_join. r.table("posts").eq_join("id",
r.table("users"),
:index => "id"
).zip() |
SELECT posts.id AS post_id,
user.name,
users.id AS user_id
FROM posts
JOIN users
ON posts.user_id = users.id
SELECT posts.id AS post_id,
user.name,
users.id AS user_id
FROM posts
INNER JOIN users
ON posts.user_id = users.id |
r.table("posts").inner_join(
r.table("users")
) { |post, user|
post["user_id"] == user["id"]
}.map { |post, user|
:post_id => post["id"],
:user_id => user["id"],
:name => user["name"]
} |
SELECT *
FROM posts
RIGHT JOIN users
ON posts.user_id = users.id
SELECT *
FROM posts
RIGHT OUTER JOIN users
ON posts.user_id = users.id |
r.table("posts").outer_join(
r.table("users")
) { |post, user|
post["user_id"] == user["id"]
}.zip() Note: You can perform more efficient r.table("posts").concat_map{ |post|
r.table("users").get_all(
post["id"], :index => "id"
).do{ |results| r.branch(
results.count() == 0,
[{:left => post}],
results.map { |user|
{:left => post, :right => user}
}
)}
}.zip() |
SELECT *
FROM posts
LEFT JOIN users
ON posts.user_id = users.id
SELECT *
FROM posts
LEFT OUTER JOIN users
ON posts.user_id = users.id |
r.table("posts").outer_join(
r.table("users")
) { |user, post|
post["user_id"] == user["id"]
}.zip() r.table("posts").concat_map{ |post|
r.table("users").get_all(
post["id"], :index => "id"
).do{ |results| r.branch(
results.count() == 0,
[{:left => user}],
results.map { |post|
{:left => user, :right => post}
}
)}
}.zip() |
This is a list of queries for performing data aggregation.
| SQL | ReQL |
|---|---|
SELECT category
FROM posts
GROUP BY category |
r.table("posts").map{ |doc|
doc["category"]
}.distinct() |
SELECT category,
SUM('num_comments')
FROM posts
GROUP BY category |
r.table('posts')
.group('category')
.sum('num_comments') |
SELECT category,
status,
SUM('num_comments')
FROM posts
GROUP BY category, status |
r.table("posts")
.group('category', 'status')
.sum('num_comments') |
SELECT category,
SUM(num_comments)
FROM posts
WHERE num_comments > 7
GROUP BY category |
r.table("posts").filter{ |doc|
doc['num_comments'] > 7
}.group('category')
.sum('num_comments') |
SELECT category,
SUM(num_comments)
FROM posts
GROUP BY category
HAVING num_comments > 7 |
r.table("posts")
.group('category')
.sum('num_comments')
.ungroup()
.filter{ |doc|
doc["reduction"] > 7
} |
SELECT title,
COUNT(title)
FROM movies
GROUP BY title
HAVING COUNT(title) > 1 |
r.table("movies")
.group("title")
.count()
.ungroup()
.filter{ |doc|
doc["reduction"] > 1
} |
This is a list of queries for creating and dropping tables and databases.
| SQL | ReQL |
|---|---|
CREATE DATABASE my_database; |
r.db_create('my_database') |
DROP DATABASE my_database; |
r.db_drop('my_database') |
CREATE TABLE users
(id INT IDENTITY(1,1) PRIMARY KEY,
name VARCHAR(50),
age INT); |
r.table_create('users',
:primary_key => "id") Note: RethinkDB is a NoSQL database and does not enforce schemas. Note: The default primary key is |
TRUNCATE TABLE users; |
r.table("users").delete() |
DROP TABLE users; |
r.table_drop("users") |
Browse the following resources to learn more about ReQL:
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/sql-to-reql/ruby/