defmodule Meilisearch.Stats do
@moduledoc """
Get Stats about your Meilisearch indexes.
[Key API](https://www.meilisearch.com/docs/reference/api/stats)
"""
use TypedEctoSchema
@primary_key false
typed_embedded_schema do
field(:databaseSize, :integer)
field(:lastUpdate, :utc_datetime)
field(:indexes, :map) :: %{String.t() => Meilisearch.Stats.Stat.t()}
end
def cast(data) when is_map(data) do
%__MODULE__{}
|> Ecto.Changeset.cast(data, [:databaseSize, :lastUpdate, :indexes])
|> cast_indexes()
|> Ecto.Changeset.apply_changes()
end
defp cast_indexes(changeset) do
indexes =
changeset
|> Ecto.Changeset.get_change(:indexes, %{})
|> Enum.map(fn {k, v} -> {k, Meilisearch.Stats.Stat.cast(v)} end)
|> Enum.into(%{})
Ecto.Changeset.put_change(changeset, :indexes, indexes)
end
@doc """
Get stats about all indexes of your Meilisearch instance.
[Meilisearch documentation](https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-all-indexes)
## Examples
iex> client = Meilisearch.Client.new(endpoint: "http://localhost:7700", key: "master_key_test")
iex> Meilisearch.Stats.all(client)
{:ok, %{
databaseSize: 447819776,
lastUpdate: ~U[2021-08-12 10:00:00],
indexes: %{
"movies" => %{
numberOfDocuments: 19654,
isIndexing: false,
fieldDistribution: %{
"poster" => 19654,
"overview" => 19654,
"title" => 19654,
"id" => 19654,
"release_date" => 19654
}
},
"books" => %{
numberOfDocuments: 5,
isIndexing: false,
fieldDistribution: %{
"id" => 5,
"title" => 5,
"author" => 5,
"price" => 5,
"genres" => 5
}
}
}
}}
"""
@spec all(Tesla.Client.t(), offset: integer(), limit: integer()) ::
{:ok, __MODULE__.t()}
| {:error, Meilisearch.Client.error()}
def all(client, opts \\ []) do
with {:ok, data} <-
client
|> Tesla.get("/stats", query: opts)
|> Meilisearch.Client.handle_response() do
{:ok, cast(data)}
end
end
@doc """
Get stats about a specific index of your Meilisearch instance.
[Meilisearch documentation](https://www.meilisearch.com/docs/reference/api/stats#get-stats-of-an-index)
## Examples
iex> client = Meilisearch.Client.new(endpoint: "http://localhost:7700", key: "master_key_test")
iex> Meilisearch.Stats.get(client, "movies")
{:ok, %{
numberOfDocuments: 19654,
isIndexing: false,
fieldDistribution: &{
"poster" => 19654,
"release_date" => 19654,
"title" => 19654,
"id" => 19654,
"overview" => 19654
}
}}
"""
@spec get(Tesla.Client.t(), String.t()) ::
{:ok, Meilisearch.Stats.Stat.t()} | {:error, Meilisearch.Client.error()}
def get(client, index_uid) do
with {:ok, data} <-
client
|> Tesla.get("/indexes/:index_uid/stats", opts: [path_params: [index_uid: index_uid]])
|> Meilisearch.Client.handle_response() do
{:ok, Meilisearch.Stats.Stat.cast(data)}
end
end
defmodule Stat do
@moduledoc """
see [documentation](https://www.meilisearch.com/docs/reference/api/stats#stats-object)
"""
use TypedEctoSchema
@primary_key false
typed_embedded_schema do
field(:numberOfDocuments, :integer)
field(:isIndexing, :boolean)
field(:fieldDistribution, :map) :: %{String.t() => integer()}
end
def cast(data) when is_map(data) do
%__MODULE__{}
|> Ecto.Changeset.cast(data, [:numberOfDocuments, :isIndexing, :fieldDistribution])
|> Ecto.Changeset.apply_changes()
end
end
end