NAME

Typesense::Client::Documents - indexing, updating and bulk loading documents

SYNOPSIS

my $d = $ts->documents;

$d->upsert('products', { id => '42', name => 'Laptop 14', price => 999.0 });
$d->update('products', '42', { price => 899.0 });       # partial
$d->delete('products', '42');
$d->delete_by_filter('products', 'stock:=0');

my $r = $d->import_docs('products', \@docs);            # JSONL, batched
warn "@{$r->{errors}}" if $r->{failed};

my $all = $d->export('products');

METHODS

create

POST /collections/{c}/documents. Fails if the id already exists; use "upsert" unless you want that.

upsert

Same endpoint with action=upsert. Creates or replaces.

get

GET /collections/{c}/documents/{id}.

update

PATCH /collections/{c}/documents/{id}. Partial: only the fields you send are touched. This is the cheap way to move one number - a stock count, a price - without rebuilding the document.

delete

DELETE /collections/{c}/documents/{id}. Deleting something that is already gone is not an error.

delete_by_filter

DELETE /collections/{c}/documents?filter_by=.... Returns { num_deleted => N }.

import_docs

my $r = $d->import_docs($collection, \@docs, %opt);

Bulk load over POST .../documents/import, in JSONL. %opt takes action (upsert by default, also create, update, emplace), batch_size and max_errors.

Returns { total, ok, failed, errors }. Check failed: Typesense answers 200 for the batch even when individual documents are rejected - it returns one JSON line per document, each with its own success flag. The HTTP status tells you the batch arrived, not that it was indexed.

The name is import_docs and not import because import is the method Perl calls by itself on every use: a sub with that name would fire without anyone calling it.

export

my $docs = $d->export($collection, %opt);
my $text = $d->export($collection, raw => 1);

GET /collections/{c}/documents/export. Returns an array reference of decoded documents, or with raw => 1 the JSONL text as it arrived - which is what you want for a large collection, since it keeps you from holding the whole catalogue decoded in memory.

%opt also passes through Typesense's own filter_by, include_fields and exclude_fields.

SEE ALSO

Typesense::Client

AUTHOR

SeHarrys

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by SeHarrys.

This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.