/arangodb_ecto

An Ecto adapter for ArangoDB.

Primary LanguageElixirMIT LicenseMIT

ArangoDB.Ecto

Ecto 2.x adapter for ArangoDB.

The aim for this adapter is for it to be a drop-in replacement for the default Postgres adapter.

It converts Ecto.Query structs to AQL.

At the moment the from, where, order_by, limit, offset, select and preload clauses are supported.

For example, this Ecto query:

from u in "users",
  where: like(u.name, "A%") and u.age > 18,
  select: [u.name, u.age],
  order_by: [desc: u.name],
  limit: 10

results in the following AQL query:

FOR u0 IN `users`
  FILTER ((u0.`name` LIKE 'A%') && (u0.`age` > 18))
  SORT u0.`name` DESC
  LIMIT 10
  RETURN { `name`: u0.`name`, `age`: u0.`age` }

Usage

In the repository configuration, you need to specify the :adapter:

config :my_app, MyApp.Repo,
  adapter: ArangoDB.Ecto,
  database: "my_app"
  ...

The following options can be defined to configure the connection to ArangoDB.
Unless specified otherwise, the shown default values are used.

host: "localhost",
port: 8529,
scheme: "http",
database: "_system",
arrango_version: 30_000,
headers: %{"Accept": "*/*"},
use_auth: :basic,
username: nil,
password: nil,

Creating collections (migrations)

The ArangoDB adapter handles table and index create statements. Since ArangoDB is schemaless, you do not need to specify fields in your migrations.
ArangoDB does have some special options when creating collections:

  • "edge": the collection type is edge
  • "uuid": the primary key type is UUID (introduced with ArangoDB 3.4)
  • "autoincrement": the primary key is autoincrementing

To define collections for storing assemblies containing assemblies:

defmodule Db.Repo.Migrations.CreateAssemblies do
  use Ecto.Migration

  def change do
    create(table(:assemblies, options: "uuid"))
    create(table(:contains, options: "edge"))
  end
end

Defining schemas

When defining your schema, you should use ArangoDB.Ecto.Schema instead of Ecto.Schema. This implicitly defines the primary key to be the autogenerated id, mapping it to Arango's _key field.

If you pass in the option arango_key: true, this translation will not be done, and your primary key will be _key. In this case, you will have to manually specify the foreign_key when using associations. E.g. foreign_key: author__key

defmodule User do
  use ArangoDB.Ecto.Schema

  schema "users" do
    field :name, :string
    field :age, :integer
    has_many :posts, Post
    timestamps()
  end
end

defmodule Post do
  use ArangoDB.Ecto.Schema

  schema "posts" do
    field :title, :string
    field :text, :binary
    belongs_to :author, User
    timestamps()
  end
end

Installation

The package can be installed by adding arangodb_ecto to your list of dependencies in mix.exs:

def deps do
  [{:arangodb_ecto, "~> 0.1.0"}]
end

To use the latest version, available on github:

def deps do
  [{:arangodb_ecto, git: "https://github.com/ArangoDB-Community/arangodb_ecto.git"}],
end

Features not yet implemented

  • subqueries
  • joins
  • on conflict
  • upserts

Testing

Before running the tests, configure access to your Arango database by setting these environment variables:

  • ARANGO_SRV
  • ARANGO_USR
  • ARANGO_PWD

More conveniently, you can start an unauthenticated Docker instance of ArangoDB with

docker run --publish 8529:8529 --env ARANGO_NO_AUTH=1 arangodb/arangodb