hamiltop/rethinkdb-elixir
{ "createdAt": "2015-04-20T14:48:34Z", "defaultBranch": "master", "description": "Rethinkdb client in pure elixir (JSON protocol)", "fullName": "hamiltop/rethinkdb-elixir", "homepage": null, "language": "Elixir", "name": "rethinkdb-elixir", "pushedAt": "2018-11-27T01:10:07Z", "stargazersCount": 492, "topics": [], "updatedAt": "2025-10-12T16:51:20Z", "url": "https://github.com/hamiltop/rethinkdb-elixir"}RethinkDB 
Section titled “RethinkDB ”UPDATE: I am not actively developing this.
Multiplexed RethinkDB client in pure Elixir.
If you are coming here from elixir-rethinkdb, welcome!
If you were expecting Exrethinkdb you are in the right place. We decided to change the name to just RethinkDB and the repo to rethinkdb-elixir. Sorry if it has caused confusion. Better now in the early stages than later!
I just set up a channel on the Elixir slack, so if you are on there join #rethinkdb.
Recent changes
Section titled “Recent changes”- Extract Changefeed out into separate package
- Accept keyword options with queries
Getting Started
Section titled “Getting Started”See API documentation for more details.
Connection
Section titled “Connection”Connections are managed by a process. Start the process by calling start_link/1. See documentation for Connection.start_link/1 for supported options.
Basic Remote Connection
Section titled “Basic Remote Connection”{:ok, conn} = RethinkDB.Connection.start_link([host: "10.0.0.17", port: 28015])Named Connection
Section titled “Named Connection”{:ok, conn} = RethinkDB.Connection.start_link([name: :foo])Supervised Connection
Section titled “Supervised Connection”Start the supervisor with:
worker(RethinkDB.Connection, [[name: :foo]])worker(RethinkDB.Connection, [[name: :bar, host: 'localhost', port: 28015]])Default Connection
Section titled “Default Connection”An RethinkDB.Connection does parallel queries via pipelining. It can and should be shared among multiple processes. Because of this, it is common to have one connection shared in your application. To create a default connection, we create a new module and use RethinkDB.Connection.
defmodule FooDatabase do use RethinkDB.ConnectionendThis connection can be supervised without a name (it will assume the module as the name).
worker(FooDatabase, [])Queries can be run without providing a connection (it will use the name connection).
import RethinkDB.Querytable("people") |> FooDatabase.runConnection Pooling
Section titled “Connection Pooling”To use a connection pool, add Poolboy to your dependencies:
{:poolboy, "~> 1.5"}Then, in your supervision tree, add:
worker(:poolboy, [[name: {:local, :rethinkdb_pool}, worker_module: RethinkDB.Connection, size: 10, max_overflow: 0], [])NOTE: If you want to use changefeeds or any persistent queries, max_overflow: 0 is required.
Then use it in your code:
db = :poolboy.checkout(:rethinkdb_pool)table("people") |> db:poolboy.checkin(:rethinkdb_pool, db)RethinkDB.run/2 accepts a process as the second argument (to facilitate piping).
Insert
Section titled “Insert”q = Query.table("people") |> Query.insert(%{first_name: "John", last_name: "Smith"}) |> RethinkDB.run connFilter
Section titled “Filter”q = Query.table("people") |> Query.filter(%{last_name: "Smith"}) |> RethinkDB.run connFunctions
Section titled “Functions”RethinkDB supports RethinkDB functions in queries. There are two approaches you can take:
Use RethinkDB operators
import RethinkDB.Query
make_array([1,2,3]) |> map(fn (x) -> add(x, 1) end)Use Elixir operators via the lambda macro
require RethinkDB.Lambdaimport RethinkDB.Lambda
make_array([1,2,3]) |> map(lambda fn (x) -> x + 1 end)require RethinkDB.Lambdaimport Queryimport RethinkDB.Lambda
conn = RethinkDB.connect
table("people") |> has_fields(["first_name", "last_name"]) |> map(lambda fn (person) -> person[:first_name] + " " + person[:last_name] end) |> RethinkDB.run connSee [query.ex]!(lib/rethinkdb/query.ex) for more basic queries. If you don’t see something supported, please open an issue. We’re moving fast and any guidance on desired features is helpful.
Indexes
Section titled “Indexes”# Simple indexes# createresult = Query.table("people") |> Query.index_create("first_name", Lambda.lambda fn(row) -> row["first_name"] end) |> RethinkDB.run conn
# retrieveresult = Query.table("people") |> Query.get_all(["Will"], index: "first_name") |> RethinkDB.run conn
# Compound indexes# createresult = Query.table("people") |> Query.index_create("full_name", Lambda.lambda fn(row) -> [row["first_name"], row["last_name"]] end) |> RethinkDB.run conn
# retrieveresult = Query.table("people") |> Query.get_all([["Will", "Smith"], ["James", "Bond"]], index: "full_name") |> RethinkDB.run connOne limitation we have in Elixir is that we don’t support varargs. So in JavaScript you would do getAll(key1, key2, {index: "uniqueness"}). In Elixir we have to do get_all([key1, key2], index: "uniqueness"). With a single key it becomes get_all([key1], index: "uniqueness") and when key1 is [partA, partB] you have to do get_all([[partA, partB]], index: "uniqueness")
Changes
Section titled “Changes”Change feeds can be consumed either incrementally (by calling RethinkDB.next/1) or via the Enumerable Protocol.
results = Query.table("people") |> Query.filter(%{last_name: "Smith"}) |> Query.changes |> RethinkDB.run conn# get one resultfirst_change = RethinkDB.next results# get stream, chunked in groups of 5, Inspectresults |> Stream.chunk(5) |> Enum.each &IO.inspect/1Supervised Changefeeds
Section titled “Supervised Changefeeds”Supervised Changefeeds (an OTP behavior for running a changefeed as a process) have been moved to their own repo to enable independent release cycles. See https://github.com/hamiltop/rethinkdb_changefeed
Roadmap
Section titled “Roadmap”Version 1.0.0 will be limited to individual connections and implement the entire documented ReQL (as of rethinkdb 2.0)
While not provided by this library, we will also include example code for:
- Connection Pooling
The goal for 1.0.0 is to be stable. Issues have been filed for work that needs to be completed before 1.0.0 and tagged with the 1.0.0 milestone.
Example Apps
Section titled “Example Apps”Checkout the wiki page for various example apps
Contributing
Section titled “Contributing”Contributions are welcome. Take a look at the Issues. Anything that is tagged Help Wanted or Feedback Wanted is a good candidate for contributions. Even if you don’t know where to start, respond to an interesting issue and you will be pointed in the right direction.
Testing
Section titled “Testing”Be intentional. Whether you are writing production code or tests, make sure there is value in the test being written.