View Source Cheatsheet Guide

Collections

Create using schema

# edit your Ecto schema
defmodule MyApp.Listings.Company do
  use Ecto.Schema
  @behaviour ExTypesense

  defimpl Jason.Encoder, for: __MODULE__ do
    def encode(value, opts) do
      value
      |> Map.take([:companies_id, :name, :country])
      |> Enum.map(fn {key, val} ->
        if key === :companies_id, do: {key, Map.get(value, :id)}, else: {key, val}
      end)
      |> Enum.into(%{})
      |> Jason.Encode.map(opts)
    end
  end

  schema "companies" do
    field(:name, :string)
    field(:country, :string)
    field(:companies_id, :integer, virtual: true)
  end

  @impl ExTypesense
  def get_field_types do
    primary_field = __MODULE__.__schema__(:source) <> "_id"

    %{
      default_sorting_field: primary_field,
      fields: [
        %{name: primary_field, type: "int32"},
        %{name: "name", type: "string"},
        %{name: "country", type: "string"}
      ]
    }
  end
end

# then try this on iex -S mix
iex> ExTypesense.create_collection(Company)
{:ok,
  %ExTypesense.Collection{
    "created_at" => 1234567890,
    "default_sorting_field" => "companies_id",
    "fields" => [...],
    "name" => "companies",
    "num_documents" => 0,
    "symbols_to_index" => [],
    "token_separators" => []
  }
}

Create using map

iex> schema =
...> %{
...>   name: "companies",
...>   fields: [
...>     %{name: "company_name", type: "string"},
...>     %{name: "companies_id", type: "int32"},
...>     %{name: "country", type: "string", facet: true}
...>   ],
...>   default_sorting_field: "companies_id"
...> }

iex> ExTypesense.create_collection(schema)
{:ok,
  %ExTypesense.Collection{
    "created_at" => 1234567890,
    "default_sorting_field" => "companies_id",
    "fields" => [...],
    "name" => "companies",
    "num_documents" => 0,
    "symbols_to_index" => [],
    "token_separators" => []
  }
}

List collections

iex> ExTypesense.list_collections()

Update a collection

iex> schema =
...> %{
...>   fields: [
...>     %{name: "num_employees", drop: true},
...>     %{name: "company_category", type: "string"},
...>   ],
...> }

iex> ExTypesense.update_collection("companies", schema)
{:ok,
  %ExTypesense.Collection{
    "created_at" => nil,
    "name" => nil,
    "default_sorting_field" => "companies_id",
    "fields" => [...],
    "num_documents" => 0,
    "symbols_to_index" => [],
    "token_separators" => []
  }
}

Documents

Index a document from an Ecto schema

iex> post = Post |> limit(1) |> Repo.one()

iex> ExTypesense.create_document(post, :create)
{:ok,
  %{
    "id" => "12",
    "posts_id" => 12,
    "title" => "the quick brown fox",
    "collection_name" => "posts"
  }
}

Update a document

iex> post = Post |> limit(1) |> Repo.one()

iex> ExTypesense.update_document(post, 0)
{:ok,
  %{
    "id" => "0",
    "collection_name" => "posts",
    "posts_id" => 34,
    "title" => "test",
    "description" => "lorem ipsum"
  }
}

Delete a document

iex> ExTypesense.delete_document(Post, 0)
{:ok,
  %{
    "id" => "0",
    "collection_name" => "posts",
    "posts_id" => 34,
    "title" => "test",
    "description" => "lorem ipsum"
  }
}

Delete a document by query

iex> query = %{
...>   filter_by: "num_employees:>100",
...>   batch_size: 100
...> }
iex> ExTypesense.delete_documents_by_query(Employee, query)
{:ok, %{}}

Indexes multiple documents

iex> posts = Post |> Repo.all()
iex> ExTypesense.index_multiple_documents(posts, :post_id, :upsert)
{:ok, [%{"success" => true}, %{"success" => true}]}

Search using Ecto schema (struct)

iex> params = %{q: "test", query_by: "title"}
iex> ExTypesense.search(Post, params)
{:ok,
  %{
    "id" => "0",
    "collection_name" => "posts",
    "posts_id" => 34,
    "title" => "test",
    "description" => "lorem ipsum"
  }
}
iex> searches = [
...>   %{collection: "companies", q: "Loca Cola"},
...>   %{collection: Company, q: "Burgler King"},
...>   %{collection: Catalog, q: "umbrella"}
...> ]
iex> ExTypesense.multi_search(searches)
{:ok,
  [
    {
      %{"facet_counts" => [], "found" => 0, "hits" => [], ...},
      %{"facet_counts" => [], "found" => 0, "hits" => [], ...},
      %{"facet_counts" => [], "found" => 0, "hits" => [], ...},
    }
  ]
}

Search using collection name (string)

iex> params = %{q: "test", query_by: "title"}
iex> ExTypesense.search("posts", params)
{:ok,
  %{
    "id" => "0",
    "collection_name" => "posts",
    "post_id" => 34,
    "title" => "test",
    "description" => "lorem ipsum"
  }
}