defmodule Typesense.Documents do @moduledoc """ Methods for interaction with Typesense Documents. """ @doc """ Index a document. ## Examples ```elixir iex> document = %{ company_name: "Stark Industries", num_employees: 5215, country: "USA" } iex> Typesense.Documents.create(collection, document) {:ok, document} ``` """ @spec create(binary(), binary() | map()) :: {:ok, map()} | {:error, any()} def create(collection, document) do Typesense.post("/collections/#{collection}/documents", document) end @doc """ Retrieve a document. ## Examples ```elixir iex> Typesense.Documents.retrieve(collection, id) {:ok, document} ``` """ def retrieve(collection, id) do Typesense.get("/collections/#{collection}/documents/#{id}") end @doc """ Search for documents. ## Examples ```elixir iex> search_params = %{ q: "stark", query_by: "company_name", filter_by: "num_employees:>100", sort_by: "num_employees:desc" } iex> Typesense.Documents.search(collection, search_params) iex> {:ok, documents} ``` """ def search(collection, query) do Typesense.get("/collections/#{collection}/documents/search", [], params: query) end @doc """ Update a document. ## Examples ```elixir iex> Typesense.Documents.update(collection, id, document) {:ok, document} ``` """ # NOTE: Need to update all the others that take a document to specify binary or map? @spec update(binary(), binary(), binary() | map()) :: {:ok, map()} | {:error, any()} def update(collection, id, document) do Typesense.patch("/collections/#{collection}/documents/#{id}", document) end @doc """ Delete a document by id, or several documents through a query. ## Examples ```elixir iex> Typesense.Documents.delete(collection, id) {:ok, _document} ``` """ @spec delete(binary(), binary() | integer() | map()) :: {:ok, map()} | {:error, any()} def delete(collection, id) when is_integer(id) or is_binary(id) do Typesense.delete("/collections/#{collection}/documents/#{id}") end def delete(collection, query) when is_map(query) do Typesense.delete("/collections/#{collection}/documents", [], params: query) end @doc """ Export documents from a collection. ## Examples ```elixir iex> Typesense.Documents.export(collection) [%{}, ...] """ def export(collection) do Typesense.get("/collections/#{collection}/documents/export", [], parse: :jsonl) end @doc """ Import documents into a collection. ## Examples ```elixir iex> documents = [%{ id: "124", company_name: "Stark Industries", num_employees: 5215, country: "USA" }] iex> Typesense.Documents.import(collection, documents, :create) {:ok, documents} """ def import(collection, documents, action \\ :create) do Typesense.post( "/collections/#{collection}/documents/import?action=#{action}", prepare_jsonl(documents), [], parse: :jsonl ) end defp prepare_jsonl(documents) when is_list(documents) do Enum.map_join(documents, "\n", &Jason.encode!/1) end defp prepare_jsonl(documents) when is_binary(documents) do documents end end