> ## Documentation Index
> Fetch the complete documentation index at: https://nikita-shkoda.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Updates (Partial & Bulk)

> Update documents by id or filter using model and relation helpers. Options, safety, and when to prefer upsert.

## Overview

Use the update helpers when you need to patch existing documents in Typesense without re-mapping the full dataset. These APIs reuse the compiled schema and validation path, and respect partition/alias resolution.

Related: <a href="/projects/search-engine-for-typesense/v30/upsert">Upsert</a>, <a href="/projects/search-engine-for-typesense/v30/deletion">Deletion</a>, <a href="/projects/search-engine-for-typesense/v30/indexer">Indexer</a>.

## APIs

### Instance: `SearchEngine::Base#update`

* Partially updates a hydrated record (uses its document id or `identify_by` fallback).
* Signature: `record.update(attrs, into: nil, partition: nil, timeout_ms: nil, cascade: nil)`.
* Returns `1` on success, `0` if nothing was updated.

```ruby theme={null}
book = SearchEngine::Book.find_by(id: "B-1")
book.update(title: "New title", price_cents: 1299, cascade: true)
```

Notes:

* `cascade: true` triggers a best-effort cascade reindex of referencing collections.
* Fails when the id cannot be determined; include `id` in selection or define `identify_by`.

### Relation: `SearchEngine::Relation#update_all`

* Updates all documents matching the current relation filters.
* Signature: `rel.update_all(attrs, into: nil, partition: nil, timeout_ms: nil)`.
* Empty relation filters fall back to a safe match-all `id:!=null`.

```ruby theme={null}
SearchEngine::Book.where(published: false).update_all(archived: true, timeout_ms: 2000)
```

### Low-level: `SearchEngine::Update.update_by`

* Filter-driven update without a relation.
* Signature: `Update.update_by(klass:, attributes:, filter: nil, hash: nil, into: nil, partition: nil, timeout_ms: nil)`.
* Accepts either a Typesense filter string (`filter:`) or a Hash converted via the Sanitizer (`hash:`).

```ruby theme={null}
SearchEngine::Update.update_by(
  klass: SearchEngine::Book,
  attributes: { featured: true },
  hash: { publisher_id: 42 },
  into: "books_20251011_120000_001"
)
```

## Options & Resolution

* `into:` — override physical collection; defaults to alias or partition resolver.
* `partition:` — forwarded to partition resolver and cascade contexts.
* `timeout_ms:` — optional read timeout override for the update request.

## When to use vs upsert/indexer

* **Use update**: targeted patches to a known set of documents; small scope; you already know ids or filters.
* **Use upsert**: when you need to re-map source records (ActiveRecord/SQL) or send pre-mapped hashes with schema validation.
* **Use indexer**: for large-scale rebuilds, partitioned workflows, or when schema drift needs to be handled.

## Safety tips

* Provide explicit filters; match-all is allowed but should be intentional.
* Keep payloads small; Typesense applies the provided fields as partial updates.
* Combine with `timeout_ms` for long-running operations, and consider `cascade: true` on instance updates when referencers exist.
