Rubber Build Status Hex.pm

A DSL-free Elasticsearch client written in Elixir (backward-compatible with elastix v0.5.0).

elastix doesn’t seem to be maintained anymore so I’ll try to keep this fork up-to-date.

I started off with elastic-reloaded for the name but then it got annoying because I wanted some consistency between the package name, the app name and the top module name so now it’s Rubber everywhere.

Documentation

Even though the documentation is pretty scarce right now, I’m working on improving it. Also if you want to help with that you’re definitely welcome 🤗

This README contains most of the information you should need to get started, if you can’t find what you’re looking for, either look at the tests or file an issue!

Installation

Add rubber to your list of dependencies in mix.exs:

def deps do
  [{:rubber, ">= 0.0.0"}]
end

Then run mix deps.get to fetch the new dependency.

Examples

Creating an Elasticsearch index

Rubber.Index.create("http://localhost:9200", "twitter", %{})

Map, Index, Search and Delete

elastic_url = "http://localhost:9200"

data = %{
    user: "kimchy",
    post_date: "2009-11-15T14:12:12",
    message: "trying out Rubber"
}

mapping = %{
  properties: %{
    user: %{type: "text"},
    post_date: %{type: "date"},
    message: %{type: "text"}
  }
}

Rubber.Mapping.put(elastic_url, "twitter", "tweet", mapping)
Rubber.Document.index(elastic_url, "twitter", "tweet", "42", data)
Rubber.Search.search(elastic_url, "twitter", ["tweet"], %{})
Rubber.Document.delete(elastic_url, "twitter", "tweet", "42")

Bulk requests

Bulk requests take as parameter a list of the lines you want to send to the _bulk endpoint.

You can also specify the following options:

  • index the index of the request
  • type the document type of the request. (you can’t specify type without specifying index)
lines = [
  %{index: %{_id: "1"}},
  %{field: "value1"},
  %{index: %{_id: "2"}},
  %{field: "value2"}
]

Rubber.Bulk.post(elastic_url, lines, index: "my_index", type: "my_type")

# You can also send raw data:
data = Enum.map(lines, fn line -> Poison.encode!(line) <> "\n" end)
Rubber.Bulk.post_raw(elastic_url, data, index: "my_index", type: "my_type")

Configuration

Shield

config :rubber,
  shield: true,
  username: "username",
  password: "password",

Poison (or any other JSON library) and HTTPoison

config :rubber,
  json_options: [keys: :atoms!],
  httpoison_options: [hackney: [pool: :rubber_pool]]

Note that you can configure Rubber to use any JSON library, see the “Custom JSON codec” page for more info.

Custom headers

config :rubber,
  custom_headers: {MyModule, :add_aws_signature, ["us-east"]}

custom_headers must be a tuple of the type {Module, :function, [args]}, where :function is a function that should accept the request (a map of this type: %{method: String.t, headers: [], url: String.t, body: String.t}) as its first parameter and return a list of the headers you want to send:

defmodule MyModule do
  def add_aws_signature(request, region) do
    [{"Authorization", generate_aws_signature(request, region)} | request.headers]
  end

  defp generate_aws_signature(request, region) do
    # See: https://github.com/bryanjos/aws_auth or similar
  end
end

Running tests

You need Elasticsearch running locally on port 9200. A quick way of doing so is via Docker:

$ docker run -p 9200:9200 -it --rm elasticsearch:5.1.2

Then clone the repo and fetch its dependencies:

$ git clone git@github.com:evuez/rubber.git
$ cd rubber
$ mix deps.get
$ mix test

License

elastix was first licensed under the WTFPL by El Werbitzky werbitzky@gmail.com. Rubber is now distributed under the MIT License.