Elastix

repository·master·Indexed 42 days ago

https://github.com/werbitzky/elastix

A DSL-free Elasticsearch client for Elixir that provides direct interaction with Elasticsearch via structured modules. It includes interfaces for the Bulk, Document, Index, Mapping, Search, and Alias APIs, allowing for indexing, searching, and bulk operations without the overhead of a complex domain-specific language.

Tokens
7.3K
Snippets
45
Records
46
Agent score
54%

What's inside Elastix

  1. Configure a custom JSON codec for Elastix

    master

    By default, Elastix uses a standard JSON library, but you can swap it for a different one (like Jiffy or Jason) by configuring the json_codec and json_options keys in your application configuration.

    To use a custom library, you must provide a module that implements the Elastix.JSON.Codec behavior. This behavior requires two functions:

    1. encode!(data): Encodes Elixir data to a JSON string.
    2. decode(json, opts \ []): Decodes a JSON string into Elixir data, returning {:ok, decoded_data} or an error tuple.

    If the library you are using already implements this interface (for example, Jason), you can pass the module name directly.

    # Example: Using Jiffy with specific options
    config :elastix,
      json_codec: JiffyCodec,
      json_options: [:return_maps]
    
    # Example: Implementing the Elastix.JSON.Codec behavior
    defmodule JiffyCodec do
      @behaviour Elastix.JSON.Codec
    
      def encode!(data), do: :jiffy.encode(data)
      def decode(json, opts \ []), do: {:ok, :jiffy.decode(json, opts)}
    end
    
    # Example: Using Jason (which already implements the interface)
    config :elastix,
      json_codec: Jason
  2. Implement Custom Headers

    master

    You can inject custom headers into requests using the custom_headers configuration key. This must be a tuple in the format {Module, :function, [args]}.

    The function must accept a request map as its first parameter and return a list of headers. The request map has the following structure:

    %{method: String.t, headers: [], url: String.t, body: String.t}```
    
    ```elixir
    # Configuration
    config :elastix,
      custom_headers: {MyModule, :add_aws_signature, ["us-east"]}
    
    # Implementation
    defmodule MyModule do
      def add_aws_signature(request, region) do
        # request is %{method: ..., headers: [...], url: ..., body: ...}
        [{"Authorization", generate_aws_signature(request, region)} | request.headers]
      end
    
      defp generate_aws_signature(request, region) do
        # Implementation logic
      end
    end
  3. Overview of Elastix modules

    master

    Elastix is a library designed to match the Elasticsearch API through several specialized modules. It provides a way to perform raw requests via Elastix.HTTP and allows for custom JSON library integration via Elastix.JSON.

    The core API functionality is organized into the following modules:

  4. Configure JSON and HTTPoison options

    master

    You can pass configuration for the JSON library (e.g., json_options) and HTTPoison (e.g., httpoison_options) via the :elastix application config.

    config :elastix,
      json_options: [keys: :atoms!],
      httpoison_options: [hackney: [pool: :elastix_pool]]
  5. Map, Index, Search, and Delete documents

    master

    The following sequence demonstrates common CRUD and search operations using the Elastix modules:

    1. Set Mapping: Elastix.Mapping.put(url, index, type, mapping) defines the schema for a document type.
    2. Index Document: Elastix.Document.index(url, index, type, id, data) stores a document.
    3. Search: Elastix.Search.search(url, index, types, query_params) searches across specified types.
    4. Delete: Elastix.Document.delete(url, index, type, id) removes a document by ID.
    elastic_url = "http://localhost:9200"
    
    data = %{
        user: "kimchy",
        post_date: "2009-11-15T14:12:12",
        message: "trying out Elastix"
    }
    
    mapping = %{
      properties: %{
        user: %{type: "text"},
        post_date: %{type: "date"},
        message: %{type: "text"}
      }
    }
    
    Elastix.Mapping.put(elastic_url, "twitter", "tweet", mapping)
    Elastix.Document.index(elastic_url, "twitter", "tweet", "42", data)
    Elastix.Search.search(elastic_url, "twitter", ["tweet"], %{})
    Elastix.Document.delete(elastic_url, "twitter", "tweet", "42")
  6. Perform Bulk requests

    master

    Bulk requests use the _bulk endpoint to process multiple operations at once. You can provide a list of maps representing the lines to be sent, or send raw data strings.

    Options:

    • index: The index of the request.
    • type: The document type (cannot be specified without index).
    • httpoison_options: Configuration passed directly to HTTPoison methods.
    lines = [
      %{index: %{_id: "1"}},
      %{field: "value1"},
      %{index: %{_id: "2"}},
      %{field: "value2"}
    ]
    
    # Using structured maps
    Elastix.Bulk.post(elastic_url, lines, index: "my_index", type: "my_type", httpoison_options: [timeout: 180_000])
    
    # Using raw data (newline-delimited JSON)
    data = Enum.map(lines, fn line -> Poison.encode!(line) <> "\n" end)
    Elastix.Bulk.post_raw(elastic_url, data, index: "my_index", type: "my_type")
  7. Check if an index exists with Elastix.Index.exists?/2

    master

    Use Elastix.Index.exists?/2 to verify the presence of an index. It performs a HEAD request and returns {:ok, true} if the status code is 200, or {:ok, false} if the status code is 404.

    Elastix.Index.exists?("http://localhost:9200", "twitter")
    # Returns {:ok, true} or {:ok, false}
  8. Retrieve mapping information with `Elastix.Mapping.get/5`

    master

    Use Elastix.Mapping.get/5 to fetch information about mappings. This function is flexible and supports various combinations of single or multiple index names and type names.

    Arguments:

    • elastic_url: The base URL of your Elasticsearch instance.
    • index_names: A single index name (String) or a list of index names.
    • type_names: A single type name (String) or a list of type names.
    • query_params: An optional keyword list for query parameters.
    # Get mapping for a specific index and type
    Elastix.Mapping.get("http://localhost:9200", "twitter", "tweet")