ExTypesense.Document (ExTypesense v2.0.0)
View SourceModule for CRUD operations for documents. Refer to this doc guide.
Summary
Functions
Deletes all documents in a collection.
Delete an individual document from a collection by using its document ID.
Deletes documents in a collection by query.
Export all documents in a collection in JSON lines format.
Fetch an individual document from a collection by using its ID.
Imports/Indexes multiple documents via maps.
Indexes a single document using struct or map. When using struct, the pk maps to document's id as string.
Update an single document using struct or map. The update can be partial.
Update documents with conditional query
Functions
@spec delete_all_documents(module() | String.t()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Deletes all documents in a collection.
On using this function
As of this writing (v0.5.0), there's no built-in way of deleting
all documents via Typesense docs.
This function uses delete_documents_by_query/2
under the hood.
@spec delete_all_documents( module() | String.t(), keyword() ) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as delete_all_documents/1.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.delete_all_documents("persons", conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.delete_all_documents("persons", conn: conn)
iex> opts = [conn: conn]
iex> ExTypesense.delete_all_documents(MyModule.Accounts.Person, opts)
@spec delete_document(map() | struct()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Delete an individual document from a collection by using its document ID.
Options
ignore_not_found
: (Boolean) Ignore the error and treat the deletion as success. This option is only available when payload is map, not struct.
Deleting a document by id
Deleting a document means the Typesense document ID, NOT the
ID of the record itself. If you want to delete the ID of record,
use ExTypesense.delete_documents_by_query/2
Examples
iex> ExTypesense.create_collection(Post)
iex> post = Post |> limit(1) |> Repo.one()
iex> ExTypesense.index_document(post)
{:ok,
%{
id: "1",
posts_id: 99,
title: "our first post",
collection_name: "posts"
}
}
iex> ExTypesense.delete_document(post)
iex> schema = %{
...> name: "posts",
...> fields: [
...> %{name: "title", type: "string"}
...> ],
...> }
...> ExTypesense.create_collection(schema)
iex> post =
...> %{
...> id: "12",
...> collection_name: "posts",
...> posts_id: 22,
...> title: "the quick brown fox"
...> }
iex> ExTypesense.index_document(post)
iex> ExTypesense.delete_document("posts", "12", ignore_not_found: true)
{:ok,
%{
id: "12",
posts_id: 22,
title: "the quick brown fox",
collection_name: "posts"
}
}
@spec delete_document( map() | OpenApiTypesense.Connection.t() | String.t(), String.t() | keyword() ) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as delete_document/1.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.delete_document(document, conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.delete_document(struct, conn: conn)
iex> opts = [ignore_not_found: true, conn: conn]
iex> ExTypesense.delete_document(struct, opts)
@spec delete_document(String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as delete_document/2.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.delete_document("persons", "88", conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.delete_document("persons", "88", conn: conn)
iex> opts = [ignore_not_found: true, conn: conn]
iex> ExTypesense.delete_document("persons", "88", opts)
@spec delete_documents_by_query( String.t() | module(), keyword() ) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Deletes documents in a collection by query.
Options
conn
: The custom connection map or struct you passedbatch_size
: Batch size parameter controls the number of documents that should be deleted at a time. A larger value will speed up deletions, but will impact performance of other operations running on the server.filter_by
: Filter results by a particular value(s) or logical expressions. multiple conditions with &&.
Filter and batch size
To delete all documents in a collection, you can use a filter that
matches all documents in your collection. For eg, if you have an
int32 field called popularity in your documents, you can use
filter_by: "popularity:>0"
to delete all documents. Or if you have a
bool field called in_stock
in your documents, you can use
filter_by: "in_stock:[true,false]"
to delete all documents.
Use the batch_size
to control the number of documents that should
deleted at a time. A larger value will speed up deletions, but will
impact performance of other operations running on the server.
Filter parameters can be found here: https://typesense.org/docs/latest/api/search.html#filter-parameters
Examples
iex> query = [filter_by: "num_employees:>100", batch_size: 100]
iex> ExTypesense.delete_documents_by_query(Employee, query)
{:ok, [...]}
iex> conn = %{api_key: xyz, host: ...}
iex> opts = Keyword.put(query, :conn, conn)
iex> ExTypesense.delete_documents_by_query(Employee, opts)
@spec export_documents(String.t() | module()) :: {:ok, String.t()} | {:error, OpenApiTypesense.ApiResponse.t()}
Export all documents in a collection in JSON lines format.
Options
filter_by
: Filter conditions for refining your search results. Separate multiple conditions with &&.include_fields
: List of fields from the document to include in the search resultexclude_fields
: List of fields from the document to exclude in the search result
@spec export_documents( String.t() | module(), keyword() ) :: {:ok, String.t()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as export_documents/1.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.export_documents("persons", conn: conn)
iex> ExTypesense.export_documents(MyModule.Accounts.Person, conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.export_documents("persons", conn: conn)
iex> opts = [conn: conn]
iex> ExTypesense.export_documents(MyModule.Accounts.Person, opts)
@spec get_document(module() | String.t(), String.t()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Fetch an individual document from a collection by using its ID.
Options
include_fields
: (Comma-separated values) List of fields that should be present in the returned document.exclude_fields
: (Comma-separated values) List of fields that should not be present in the returned document.
Examples
iex> schema = %{
...> name: "posts",
...> fields: [
...> %{name: "title", type: "string"}
...> ],
...> }
...> ExTypesense.create_collection(schema)
...> post = %{
...> id: "22"
...> posts_id: 444,
...> collection_name: "posts",
...> title: "the quick brown fox"
...> }
iex> ExTypesense.index_document(post)
iex> ExTypesense.get_document("posts", "22", exclude_fields: "title,posts_id")
{:ok,
%{
id: "22",
collection_name: "posts"
}
}
@spec get_document(module() | String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as get_document/2.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.get_document("persons", "88", exclude_fields: "name", conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.get_document(MyModule.Accounts.Person, "88", exclude_fields: "name", conn: conn)
iex> opts = [exclude_fields: "name", conn: conn]
iex> ExTypesense.get_document(MyModule.Accounts.Person, "88", opts)
@spec import_documents(String.t() | module(), [struct()] | [map()]) :: {:ok, [map()]} | {:error, OpenApiTypesense.ApiResponse.t()}
Imports/Indexes multiple documents via maps.
You can feed the output file from a Typesense export operation directly as import.
Options
batch_size
: Batch size parameter controls the number of documents that should be imported at a time. A larger value will speed up deletions, but will impact performance of other operations running on the server.return_id
: Returning the id of the imported documents. If you want the import response to return the ingested document's id in the response, you can use the return_id parameter.remote_embedding_batch_size
: Max size of each batch that will be sent to remote APIs while importing multiple documents at once. Using lower amount will lower timeout risk, but increase number of requests made. Default is 200.remote_embedding_timeout_ms
: How long to wait until an API call to a remote embedding service is considered a timeout during indexing. Default is 60_000 msremote_embedding_num_tries
: The number of times to retry an API call to a remote embedding service on failure during indexing. Default is 2.return_doc
: Returns the entire document back in response.action
: Additional action to performdirty_values
: Dealing with Dirty Data
Examples
iex> schema = %{
...> name: "posts",
...> fields: [
...> %{name: "title", type: "string"}
...> ],
...> }
...> ExTypesense.create_collection(schema)
# doesn't matter if atom or string keys
# import using a list of maps
iex> posts = [
...> %{title: "the quick brown fox"},
...> %{title: "jumps over the lazy dog"}
...> ]
...> ExTypesense.import_documents("posts", posts)
{:ok, [%{"success" => true}, %{"success" => true}]}
# import using Ecto records
iex> posts = MyApp.Blog.Post |> Repo.all()
...> ExTypesense.import_documents("posts", posts)
@spec import_documents(String.t() | module(), [struct()] | [map()], keyword()) :: {:ok, [map()]} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as import_documents/2.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.import_documents("users", documents, conn: conn)
iex> ExTypesense.import_documents(MyApp.Accounts.User, documents, conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.import_documents(MyApp.Accounts.User, structs, conn: conn)
iex> ExTypesense.import_documents("users", [%MyApp.Accounts.User{}], conn: conn)
iex> opts = [conn: conn]
iex> ExTypesense.import_documents("users", documents, opts)
@spec index_document(map() | struct()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Indexes a single document using struct or map. When using struct, the pk maps to document's id as string.
indexing your document as a map
when using maps as documents using index_document/1
,
you should pass a key named collection_name
.
on using struct
Please refer on this page for more info on how to setup with Ecto Schema.
Options
action
: "create" (default), "upsert", "update", "emplace"dirty_values
: Dealing with Dirty Data
Examples
iex> schema = %{
...> name: "posts",
...> fields: [
...> %{name: "title", type: "string"}
...> %{name: "posts_id", type: "int32"}
...> %{name: "description", type: "string"}
...> ],
...> }
iex> ExTypesense.create_collection(schema)
iex> body =
...> %{
...> id: "34", # you can omit this key, Typesense will generate for you.
...> posts_id: 28,
...> title: "the quick brown fox",
...> description: "jumps over the lazy dog"
...> }
iex> ExTypesense.index_document("posts", body)
{:ok,
%{
id: "34",
posts_id: 28,
title: "the quick brown fox",
description: "jumps over the lazy dog"
}
}
iex> MyApp.Blog.Post |> ExTypesense.create_collection()
iex> post = MyApp.Blog.get_post!(24)
iex> ExTypesense.index_document(post)
@spec index_document(map() | struct() | String.t(), map() | keyword()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as index_document/1.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.index_document("persons", document, conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.index_document(document, conn: conn)
iex> ExTypesense.index_document(struct, conn: conn)
iex> opts = [action: "upsert", conn: conn]
iex> ExTypesense.index_document(struct, opts)
@spec index_document(String.t(), map(), keyword()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as index_document/2.
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.index_document("persons", document, action: "update", conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.index_document("persons", document, conn: conn)
iex> opts = [action: "upsert", conn: conn]
iex> ExTypesense.index_document("persons", document, opts)
@spec update_document(map() | struct()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Update an single document using struct or map. The update can be partial.
Note: the return type for struct and map are different. See examples below.
indexing your document as a map
when using map as document, you should pass a key named collection_name
.
Options
dirty_values
: Dealing with Dirty Data
Examples
iex> schema = %{
...> name: "posts",
...> fields: [
...> %{name: "title", type: "string"}
...> ],
...> }
iex> ExTypesense.create_collection(schema)
iex> post =
...> %{
...> id: "94",
...> collection_name: "posts",
...> posts_id: 94,
...> title: "the quick brown fox"
...> }
iex> ExTypesense.index_document(post)
iex> updated_post =
...> %{
...> id: "94",
...> collection_name: "posts",
...> posts_id: 94,
...> title: "test"
...> }
iex> ExTypesense.update_document(updated_post)
{:ok,
%{
id: "94",
collection_name: "posts",
posts_id: 94,
title: "sample post"
}
}
iex> person = Accounts.fetch_person!(12)
...> ExTypesense.update_document(person)
{:ok,
%OpenApiTypesense.Documents{
num_deleted: nil,
num_updated: 1
}
}
@spec update_document( map() | struct(), keyword() ) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Same as update_document/1.
Options
conn
: The custom connection map or struct you passed
Examples
iex> conn = %{api_key: xyz, host: ...}
iex> ExTypesense.update_document(document, conn: conn)
iex> conn = OpenApiTypesense.Connection.new()
iex> ExTypesense.update_document(%User{...}, conn: conn)
iex> opts = [dirty_values: "reject", conn: conn]
iex> ExTypesense.update_document(document, opts)
@spec update_documents_by_query(String.t() | module(), map(), keyword()) :: {:ok, map()} | {:error, OpenApiTypesense.ApiResponse.t()}
Update documents with conditional query
The filter_by query parameter is used to filter to specify a condition against which the
documents are matched. The request body contains the fields that should be updated for
any documents that match the filter condition. This endpoint is only available if the
Typesense server is version 0.25.0.rc12
or later.
See: https://typesense.org/docs/latest/api/search.html#filter-parameters
regarding filter_by
option.
Options
conn
: The custom connection map or struct you passedfilter_by
: Filter results by a particular value(s) or logical expressions. multiple conditions with &&.action
: Additional action to perform
Example
iex> body = %{
...> "tag" => "large",
...> }
iex> conn = %{api_key: xyz, host: ...}
iex> opts = [filter_by: "num_employees:>1000", conn: conn]
iex> ExTypesense.update_documents_by_query("companies", body, opts)
iex> ExTypesense.update_documents_by_query("companies", body, action: "upsert", conn: conn)