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}]}
How to use search
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"
}
}
Multi search
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"
}
}