ReQL means RethinkDB query language. It offers a powerful and easy way to perform operations on JSON documents. It is one of the most important parts of the RethinkDB architecture. It is built on three important principles: embedding ReQL in a programming language, ReQL queries being chainable, and ReQL queries being executed on the server.
Here is a list of topics we are going to cover, along with the mentioned principles:
Let us look over each one of them.
RethinkDB provides client drivers for various programming languages. To explain, I am going to consider Node.js, and the steps are as follows:
npm install rethinkdb
before running the following code:var rethinkdb = require('rethinkdb'); var connection = null; rethinkdb.connect({host : 'localhost', port : 28015},function(err,conn) { if(err) { throw new Error('Connection error'); } else { connection = conn; } });
The preceding simple code snippet written in Node.js is importing the rethinkdb
module and connecting to the RethinkDB server on the default port. It returns the callback
function with error
and the connection
variable, and upon getting the connection
object, we are good to go!
By default, RethinkDB creates and connects to the default database named test
. We can perform various operations on it such as creating a table or performing CRUD operations.
Let's begin with creating a simple table to store blog posts as follows:
rethinkdb.db('test').tableCreate('authors') .run(connection, function(err, result) { if (err) throw err; console.log(JSON.stringify(result));
Upon running the code, you should get the following on your console:
{ "config_changes":[ { "new_val":{ "db":"test", "durability":"hard", "id":"a168e362-b7e7-4260-8b93-37ee43430bac", "indexes":[ ], "name":"authors", "primary_key":"id", "shards":[ { "nonvoting_replicas":[ ], "primary_replica":"Shahids_MacBook_Air_local_pnj", "replicas":[ "Shahids_MacBook_Air_local_pnj" ] } ], "write_acks":"majority" }, "old_val":null } ], "tables_created":1 }
In our code, we need to check out the tables_created
key in order to determine whether the table was created or not.
We can check whether the table was created or not in the administrative web console too. Point your browser to
http://localhost:8080
and go to the DATABASE section from the menu. You should be able to see something like the following:
In order to run the code in Node.js, since you get the connection
object in callback and it's asynchronous, you need to manage the flow of the code. For now, you can just paste the code to create a table inside the closure callback of the connection and it should work fine. But when writing code for production, make sure you handle the callback flow well and do not end up being in a callback hell situation.
One of the best ways to manage it and which I use very frequently while coding Node.js programs is by using the async node module. It has a rich set of functions to properly manage and design your code. Of course, there will be no chance of callback hell and you can by far manage not to go for more than four levels of nesting (three is ideal but very tricky to reach).
We have our database up and running and we have created the table using our code. The next is to performing the very famous CRUD (Create, read, update and delete) operation on the table. This will not only cover some important functions of the RethinkDB query language but also will give a quick kick to perform basic operations, which you have probably been doing in other NoSQL and SQL databases.
Let's begin by creating a fresh new table named users
and perform CRUD operations using ReQL queries as follows:
varrethinkdb = require(''rethinkdb''rethinkdb'); var connection = null; rethinkdb.connect({host : ''localhost''localhost', port : 28015},function(err,conn) { if(err) { throw new Error(''Connection error''Connection error'); } else { connection = conn; } });
We will use the default database to perform this operation. After getting the connection, we will create a table using the following code:
rethinkdb.db('test','test').tableCreate('authors','authors').run(connection, function(err, result) { if (err) throw err; console.log(JSON.stringify(result)); }); });
Make sure that this piece of code is placed correctly within the else section of the connection code. Since we have created the table, we can perform the operation on it.
ReQL provides the insert()
function to create new documents in the table. Here is the code to do so.:
rethinkdb.db('test','test').table('users','users').insert({ userId : "shahid", password : "password123", createdDate : new Date() }).run(connection,function(err,response) { if(err) { throw new Error(err); } console.log(response); });
Upon running the code, RethinkDB returns the following.:
{ deleted: 0, errors: 0, generated_keys: [ ''e54671a0'e54671a0-bdcc-44ab-99f3-90a44f0291f8'' ], inserted: 1, replaced: 0, skipped: 0, unchanged: 0 }
Providing database details is optional in the query. The key to look for in the code is inserted
, which determines whether the document was inserted or not. Since we are not providing the primary key from our side, RethinkDB generates it automatically and you can find that in the generated_keys
.
You can add much more complex data in the RethinkDB than you can do in any other NoSQL database. You can also store nested objects, arrays, binary objects, and so on. We will look over binary objects in the upcoming section.
You can read the documents from the table using the get()
or getAll()
ReQL method. Here is a query to retrieve all the documents present in the table:
rethinkdb.table('users','users').run(connection,function(err,cursor) { if(err) { throw new Error(err); } cursor.toArray(function(err,result) { console.log(result); }); });
The preceding code performs the read operation in the table and returns you cursor
. Cursor
provides a batch of data in sequence instead of whole data at once. We use the toArray()
function to read the information in the batch. It should print the following on the console:
[ { createdDate: 2016-06-09T08:58:15.324Z, id: ''e54671a0'e54671a0-bdcc-44ab-99f3-90a44f0291f8'', password: ''password123'''password123', userId: ''shahid'''shahid' } ]
You can also read specific data based on the filter. Let's try to read the data with the uniquely generated ID the using the get()
method as follows:
rethinkdb.table('users').get('e54671a0-bdcc-44ab-99f3-90a44f0291f8') .run(connection,function(err,data) { if(err) { throw new Error(err); } console.log(data); });
It will return a single document from the table without the cursor. You can get the response in the callback variable.
As you may have noticed, we are directly accessing the table in the query without passing the database name because the connection
variable contains the database information.
You can perform the update operation on the document using the update()
function which accepts the object as an argument. You can at least update one key or the whole document (all keys) after fetching the document. Here is the code snippet to do so:
rethinkdb.table('users') .get('e54671a0-bdcc-44ab-99f3-90a44f0291f8') .update({userId : 'shahidShaikh'}) .run(connection,function(err,response) { if(err) { throw new Error(err); } console.log(response); });
In order to update the document, we first fetch it using the get()
method and then running the update()
function. We are just updating the userId
key here but you can pass other keys as well.
It will return the following on the console:
{ deleted: 0, errors: 0, inserted: 0, replaced: 1, skipped: 0, unchanged: 0 }
The key to look for in the code is replaced
, which, if it returns 1
, means the update operation is successfully committed; otherwise, in the case of any other value, there is an error.
You can also use replace()
ReQL method to replace the entire document with a new document. This method generates a new document and do not preserve the same ID as the update()
method does.
You can validate the data by either running the get()
method again or running the following code in the web administrative console:
r.db('test').table('users').get('e54671a0-bdcc-44ab-99f3-90a44f0291f8')
We can use the delete()
ReQL commands to perform a deletion. Again we need to fetch the record first and then perform the delete operation. You can perform a delete all operation as well by first fetching all documents. Here is the code to do so:
rethinkdb.table('users') .get('e54671a0-bdcc-44ab-99f3-90a44f0291f8') .delete() .run(connection,function(err,response) { if(err) { throw new Error(err); } console.log(response); });
This should print the following on the terminal:
{ deleted: 1, errors: 0, inserted: 0, replaced: 0, skipped: 0, unchanged: 0 }
You can check out the deleted
key to know the status of the delete operation. If you want to delete all the documents from the database, you can do so by selecting all documents first and appending the delete()
operation as follows:
rethinkdb.table('users') .delete() .run(connection,function(err,response) { if(err) { throw new Error(err); } console.log(response); });
3.16.212.217