1. Welcome

Introduction

Welcome to my readers. I appreciate your purchase. This will help me continue improving the book content.

Before we go into the technical details, I have something to say.

Firstly, I’m not a RethinkDB expert at all. I’m just an average guy who loves programming and new technologies. To me, RethinkDB is a pleasure to use. However, due to its age, there are not many books and documents about it comparing to other database systems. While the RethinkDB cocumentation and API is very good, it can be hard to know where to start. So this guide is for all those in mind who are unsure about taking the plunge into RethinkDB as something totally new. I hope this helps them ease into the learning process.

The purpose of this book is to organize the concepts of RethinkDB in order to help you to read and understand the RethinkDB API directly. Upon finishing the book, you will have a foundational knowledge in which to extend your knowledge with many other RethinkDB videos and blog posts out on the Internet.

Secondly, I’m a fan of Mixu’s1 writing style2. I won’t cover deeply things like installing RethinkDB, fine-tuning, extra function parameters, and so on. Those topics are covered very well on RethinkDB’s documention itself. What I want you to take away from this book is a good grasp on RethinkDB usage in practice. and how to apply commands in real scenarios.

Third, I’m not fluent in English. If you find any mistakes, you can report the issue on repository or email me directly.

Fourth, RethinkDB is changing so fast that things in this book may not reflect its current state. Once again, I’d be very grateful for any errata you may point out, via my email or Github. Since this is a LeanPub book, once I update you may download it again free of charge.

And finally, due to my limited knowledge with RethinkDB, I want to keep this book short and straight to the point. Expect a book of around 200 pages. My goal is for this to be a book that you can pick up, read on the train while riding to work and after a week you can sit down and actually start your first RethinkDB project without hesitation.

  1. http://blog.mixu.net/
  2. http://blog.mixu.net/2012/07/26/writing-about-technical-topics-like-its-2012/

Why learn RethinkDB?

RethinkDB is mind-blowing to me. I like the beauty and nature of ReQL which is built into the language. It is also very developer friendly with its own administrator UI. RethinkDB is very easy to learn, because its query language is natural to how we think when constructing a query. We can easily tell what ReQL will do and what is the execution order of the query.

Take this SQL query:

1 SELECT * FROM users WHERE name="Vinh" ORDER BY id DESC LIMIT 10,100

This query is passed as a string and occaisionally you may sometimes forget the ordering or syntax. Will we put **ORDER** before or after **LIMIT**? Where the WHERE clause should appear? We also can’t be certain if an index will be used. Because SQL is a string, the order of execution is defined by the syntax. Memorizing that syntax is essential.

Compare this with ReQL (RethinkDB Query Language):

1 r.table('users').getAll('vinh', {index: 'name'}).order_by(r.desc(id)).limit(10)

We can easily ascertain (or ‘grok’) immediately what will result from this query, and the order of execution is clear to us. This is because the methods are chained, one after another, from left too right. ReQL was designed with the intention of a very clear API but without the ambiguity that comes with an ORM.

We can also see that it will use an index **name** when finding data. The way the query is constructed, feels similiar to jQuery if you are a front-end developer who never works with databases. Or if you are a functional programming person, you probably see the similarity immediately.

If the above example hasn’t convinced you, then check this out:

1 SELECT *
2 FROM foods as f
3 INNER JOIN compounds_foods as c ON c.food_id=f.id
4 WHERE f.id IN (10, 20)
5 ORDER By f.id DESC, c.id ASC

The same query represented as ReQL would look like this:

1 r.db("food")
2   .table("foodbase")
3   .filter(function (food) {
4     return r.expr([10, 20]).contains(food("id"))
5   })
6   .eqJoin("id", r.db("foodbase").table("compound_foods"), {index: "food_id"})

Even if you are not completely familar with the syntax, you can guess what is going to happen. In ReQL, we are taking the foodbase database, and table foods, and filtering them and filtering the result with another table called compound_foods. Within the filter, we pass an anonymous function which determines if the “id” field of document is contained in the array [10, 20]. If it is either 10 or 20 then we join the results with the compound_foods table based on the id field and use an index to efficiently search. The query looks like a chain of API call and the order of execution is clear to the reader.

RethinkDB really makes me rethink how we work with database. I don’t have to write a query in a language that I don’t like. As well, I’m no longer forced to use a syntax that I don’t like because I have no choice. And further, if something does go wrong, I don’t have to slowly tear apart the entire string to find out which clause has the issue. The resulting error from a ReQL query allows me to more precisely determine the cause of error.

Furthermore, RethinkDB is explicit. Later on, you will also learn that in RethinkDB you have to explicitly tell it to do some not-very-safe operations. Such as when a non-atomic update is required, you clearly set a flag to do it. RethinkDB by default has sensible and conservative settings as a database should to help you avoid shooting yourself in the foot.

In my opinion, RethinkDB forces us to understand what we are doing. Everything is exposed on the query. No magic, no “why did this query fail on production but work as expected on my local machine”, no hidden surprises.

In Vietnamese culture, we usually follow a rule of three in demonstrations before we conclude. Being Vietnamese, let me end by showing you this third example.

Do you understand the query below?

1 r
2   .db('foodbase')
3   .table('foods')
4   .filter(r.row('created_at').year().eq(2011))

This query finds all foods which were inserted in the year 2011. I cannot even provide an equivalent SQL example, because it just cannot be as beautiful and concise as the above query.

Feedback

I appreciate all of your feedbacks to improve this book. Below is my handle on internet:

Credit

  • Sample dataset: foodb.ca/foods
  • Book cover: Design by my friend, aresta.co helps to create the cover for this book