Bungee

Hex.pm Hex.pm Hex.pm build status code coverage

About

Elasticsearch Client with Repository implementation

Installation

def deps do
  [{:bungee, "~> 1.0.0-alpha2"}]
end

Configuration

Configure the default :bungee as such:

config :bungee, :config, %{
  uri: "http://elasticsearch:9200", # Required unless Elasticsearch is available on localhost:9200
  index: "index" # Elasticsearch Index to use when repositories don't provide their own
}

Add :bungee to your supervision tree:

%{
  id: :bungee,
  start: {Bungee, :start_link, []}
}

Bungee Module

You can have as many modules using the Bungee behaviour as you require for all of the types you need to store in Elasticsearch for your application.

defmodule MyApp.KeyedType do
  defstruct identifier: nil, forename: nil, surname: nil, emails: []

  def key(type = %__MODULE__{}) do
    type.identifier
  end
end

With the corresponding repository:

defmodule MyApp.KeyedRepository do
  @moduledoc false
  use Bungee, module: Bungee.Support.KeyedType, type: "simples"
end

The type option within the repository allows you to configure where your data should be stored in your Elasticsearch index.

Note: Type’s that provide key/1 are considered KeyedTypes. All this means is that we’ll use this function to generate the document identifier when storing with Elasticsearch. UnkeyedTypes will received a randomly generated document identifier.

An unkeyed type is the same, but with no key/1 function defined.

defmodule MyApp.UnkeyedType do
  defstruct forename: nil, surname: nil, emails: []
end

Available Repository Methods

The following methods are available on your repository modules

fetch

Fetch a single document by the document identifier

MyApp.KeyedRepository.fetch("identifier-123")

save

Save a document to your index, with a status code being returned, this can be either a map or a module

{:ok, created_or_updated, projection} = MyApp.KeyedRepository.save(%MyApp.KeyedType{
  identifier: "identifier-123",
  forename: "James",
  surname: "Hetfield"
})

save!

Similar to save() but there will be no status returned

new_projection = MyApp.KeyedRepository.save!(%MyApp.KeyedType{
  identifier: "identifier-123",
  forename: "James",
  surname: "Hetfield"
})

delete

Remove an item from the Elasticsearch index

MyApp.KeyedRepository.delete("identifier-123")

fetch_by

Used when you want to fetch item(s) by a property on the document, rather than the document identifier

MyApp.UnkeyedRepository.fetch_by(:forename, "James")

Running Tests

If you wish to run the tests with Docker, run make dshell first; then the below make targets.

$ make clean deps test