View Source Algoliax.Indexer behaviour (Algoliax v0.7.1)

usage

Usage

  • :index_name: specificy the index where the object will be added on. Required
  • :object_id: specify the attribute used to as algolia objectID. Default :id.
  • :repo: Specify an Ecto repo to be use to fecth records. Default nil
  • :cursor_field: specify the column to be used to order and go through a given table. Default :id
  • :schemas: Specify which schemas used to populate index, Default: [__CALLER__]
  • :algolia: Any valid Algolia settings, using snake case or camel case. Ex: Algolia attributeForFaceting can be configured with :attribute_for_faceting

On first call to Algolia, we check that the settings on Algolia are up to date.

example

Example

defmodule People do
  use Algoliax.Indexer,
    index_name: :people,
    object_id: :reference,
    algolia: [
      attribute_for_faceting: ["age"],
      custom_ranking: ["desc(updated_at)"]
    ]

  defstruct reference: nil, last_name: nil, first_name: nil, age: nil
end

customize-object

Customize object

By default the object contains only algolia objectID. To add more attributes to objects, override build_object/1 functions to return a Map (objectID is automatically set by Algoliax)

defmodule People do
  use Algoliax.Indexer,
    index_name: :people,
    object_id: :reference,
    algolia: [
      attribute_for_faceting: ["age"],
      custom_ranking: ["desc(updated_at)"]
    ]

  defstruct reference: nil, last_name: nil, first_name: nil, age: nil

  @impl Algoliax.Indexer
  def build_object(person) do
    %{
      age: person.age,
      last_name: person.last_name,
      first_name: person.first_name
    }
  end
end

schemas

Schemas

:schemas options allows to define a list of module you want to index into the current index. By default only the module defining the indexer.

defmodule Global do
  use Algoliax.Indexer,
    index_name: :people,
    object_id: :reference,
    schemas: [People, Animal],
    algolia: [
      attribute_for_faceting: ["age"],
      custom_ranking: ["desc(updated_at)"]
    ]

end

This option allows to define also the preloads use during reindex/reindex_atomic (preload on save_object and save_objects have to be done manually)

  defmodule People do
    use Algoliax.Indexer,
      index_name: :people,
      object_id: :reference,
      schemas: [
        {__MODULE__, [:animals]}
      ]
      algolia: [
        attribute_for_faceting: ["age"],
        custom_ranking: ["desc(updated_at)"]
      ]

  end

Link to this section Summary

Callbacks

Build the object sent to algolia. By default the object contains only objectID set by Algoliax.Indexer

Configure index

Delete index

Delete object from algolia. By passing the model, the object is retrieved using the object_id configured

Fetch object from algolia. By passing the model, the object is retrieved using the object_id configured

Override this function to provide custom objectID for the model

Get index settings from Algolia

Reindex all objects (Ecto specific)

Reindex a subset of records by providing an Ecto query or query filters as a Map(Ecto specific)

Reindex atomically (Ecto specific)

Add/update object. The object is added/updated to algolia with the object_id configured.

Save multiple object at once

Search for index values

Check if current object must be indexed or not. By default it's always true. To override this behaviour override this function in your model

Link to this section Callbacks

Specs

build_object(model :: map()) :: map()

Build the object sent to algolia. By default the object contains only objectID set by Algoliax.Indexer

example

Example

@impl Algoliax.Indexer
def build_object(person) do
  %{
    age: person.age,
    last_name: person.last_name,
    first_name: person.first_name
  }
end

Specs

configure_index() :: {:ok, map()} | {:error, map()}

Configure index

Specs

delete_index() :: {:ok, map()} | {:error, map()}

Delete index

Specs

delete_object(model :: map() | struct()) ::
  {:ok, Algoliax.Response.t()} | {:error, map()}

Delete object from algolia. By passing the model, the object is retrieved using the object_id configured

example

Example

people = %People{reference: 10, last_name: "Doe", first_name: "John", age: 20}

People.delete_object(people)

Specs

get_object(model :: map() | struct()) ::
  {:ok, Algoliax.Response.t()} | {:error, map()}

Fetch object from algolia. By passing the model, the object is retrieved using the object_id configured

example

Example

people = %People{reference: 10, last_name: "Doe", first_name: "John", age: 20}

People.get_object(people)

Specs

get_object_id(model :: map()) :: binary() | :default

Override this function to provide custom objectID for the model

example

Example

@impl Algoliax.Indexer
def get_object_id(%Cat{id: id}), do: "Cat:" <> to_string(id)
def get_object_id(%Dog{id: id}), do: "Dog:" <> to_string(id)

Specs

get_settings() :: {:ok, map()} | {:error, map()}

Get index settings from Algolia

Specs

reindex(opts :: Keyword.t()) :: {:ok, [Algoliax.Response.t()]}

Reindex all objects (Ecto specific)

example

Example

People.reindex(query)

Available options:

  • :force_delete: delete objects where to_be_indexed? is false

Specs

reindex(query :: Ecto.Query.t(), opts :: Keyword.t()) ::
  {:ok, [Algoliax.Response.t()]}

Reindex a subset of records by providing an Ecto query or query filters as a Map(Ecto specific)

example

Example

import Ecto.Query

query = from(
  p in People,
  where: p.age > 45
)

People.reindex(query)

# OR
filters = %{where: [name: "john"]}
People.reindex(filters)

Available options:

  • :force_delete: delete objects that are in query and where to_be_indexed? is false

NOTE: filters as Map supports only :where and equality

Specs

reindex_atomic() :: {:ok, :completed}

Reindex atomically (Ecto specific)

Specs

save_object(object :: map() | struct()) ::
  {:ok, Algoliax.Response.t()} | {:not_indexable, model :: map()}

Add/update object. The object is added/updated to algolia with the object_id configured.

example

Example

people = %People{reference: 10, last_name: "Doe", first_name: "John", age: 20},

People.save_object(people)
Link to this callback

save_objects(models, opts)

View Source

Specs

save_objects(models :: [map()] | [struct()], opts :: Keyword.t()) ::
  {:ok, Algoliax.Response.t()} | {:error, map()}

Save multiple object at once

options

Options

  • :force_delete - if true will trigger a "deleteObject" on object that must not be indexed. Default false

example

Example

peoples = [
  %People{reference: 10, last_name: "Doe", first_name: "John", age: 20},
  %People{reference: 89, last_name: "Einstein", first_name: "Albert", age: 65}
]

People.save_objects(peoples)
People.save_objects(peoples, force_delete: true)

Specs

search(query :: binary(), params :: map()) ::
  {:ok, Algoliax.Response.t()} | {:not_indexable, model :: map()}

Search for index values

example

Example

iex> People.search("John")

{:ok,
  %{
    "exhaustiveNbHits" => true,
    "hits" => [
      %{
        "_highlightResult" => %{
          "full_name" => %{
            "fullyHighlighted" => false,
            "matchLevel" => "full",
            "matchedWords" => ["john"],
            "value" => "Pierre <em>Jon</em>es"
          }
        },
        "age" => 69,
        "first_name" => "Pierre",
        "full_name" => "Pierre Jones",
        "indexed_at" => 1570908223,
        "last_name" => "Jones",
        "objectID" => "b563deb6-2a06-4428-8e5a-ca1ecc08f4e2"
      },
      %{
        "_highlightResult" => %{
          "full_name" => %{
            "fullyHighlighted" => false,
            "matchLevel" => "full",
            "matchedWords" => ["john"],
            "value" => "Glennie <em>Jon</em>es"
          }
        },
        "age" => 27,
        "first_name" => "Glennie",
        "full_name" => "Glennie Jones",
        "indexed_at" => 1570908223,
        "last_name" => "Jones",
        "objectID" => "58e8ff8d-2794-41e1-a4ef-6f8db8d432b6"
      },
      ...
    ],
"hitsPerPage" => 20,
"nbHits" => 16,
"nbPages" => 1,
"page" => 0,
"params" => "query=john",
"processingTimeMS" => 1,
"query" => "john"
}}
Link to this callback

search_facet(facet_name, facet_query, params)

View Source

Specs

search_facet(facet_name :: binary(), facet_query :: binary(), params :: map()) ::
  {:ok, Algoliax.Response.t()} | {:not_indexable, model :: map()}

Search for facet values

example

Example

iex> People.search_facet("age")
{:ok,
  %{
    "exhaustiveFacetsCount" => true,
    "facetHits" => [
      %{"count" => 22, "highlighted" => "46", "value" => "46"},
      %{"count" => 21, "highlighted" => "38", "value" => "38"},
      %{"count" => 19, "highlighted" => "54", "value" => "54"},
      %{"count" => 19, "highlighted" => "99", "value" => "99"},
      %{"count" => 18, "highlighted" => "36", "value" => "36"},
      %{"count" => 18, "highlighted" => "45", "value" => "45"},
      %{"count" => 18, "highlighted" => "52", "value" => "52"},
      %{"count" => 18, "highlighted" => "56", "value" => "56"},
      %{"count" => 18, "highlighted" => "59", "value" => "59"},
      %{"count" => 18, "highlighted" => "86", "value" => "86"}
    ],
    "processingTimeMS" => 1
  }}

Specs

to_be_indexed?(model :: map()) :: true | false

Check if current object must be indexed or not. By default it's always true. To override this behaviour override this function in your model

example

Example

defmodule People do
  use Algoliax.Indexer,
    index_name: :people,
    object_id: :reference,
    algolia: [
      attribute_for_faceting: ["age"],
      custom_ranking: ["desc(update_at)"]
    ]

  #....

  @impl Algoliax.Indexer
  def to_be_indexed?(model) do
    model.age > 50
  end
end