> ## Documentation Index
> Fetch the complete documentation index at: https://upstash.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Document Updates

For JSON, hash, and string indexes, documents are regular Redis keys. For a stream index, each stream
entry is a separate document.

Keys matching an index prefix and entries in an indexed stream are indexed automatically. When the
indexed data changes, the index is updated automatically.

> [!NOTE]
>
> There is no separate update command for search. Use regular Redis write commands to change your data.

Any command that modifies indexed document data updates the index. For example, this includes commands such as:

* JSON commands such as `JSON.SET`, `JSON.MERGE`, ...
* Hash commands such as `HSET`, `HINCRBY`, ...
* String commands such as `SET`, `SETEX`, ...
* Stream commands such as `XADD`, `XDEL`, `XTRIM`, ...
* Generic commands such as `DEL`, `EXPIRE`, `PEXPIRE`, ...

This is not an exhaustive list. The rule is that if a command changes data represented by an indexed
document, the index is updated.

Index updates are batched for performance, so recent writes may not immediately appear in search results.
Use [`SEARCH.WAITINDEXING`](https://upstash.com/docs/redis/commands/search/search-waitindexing) when you need to ensure queries reflect recent changes.

## JSON Documents

For JSON indexes, any JSON command that modifies a matching key updates the indexed document.

> [tab] TypeScript
>
> ```ts theme={"system"}
> import { Redis } from "@upstash/redis";
>
> const redis = Redis.fromEnv();
> const products = redis.search.index({ name: "products" });
>
> await redis.json.set("product:1", "$.price", 79.99);
>
> await products.waitIndexing();
>
> const discounted = await products.query({
>   filter: { price: { $lt: 90 } },
> });
> ```

> [tab] Python
>
> ```python theme={"system"}
> from upstash_redis import Redis
>
> redis = Redis.from_env()
> products = redis.search.index(name="products")
>
> redis.json.set("product:1", "$.price", 79.99)
>
> products.wait_indexing()
>
> discounted = products.query(filter={"price": {"$lt": 90}})
> ```

> [tab] Redis CLI
>
> ```bash theme={"system"}
> JSON.SET product:1 $.price 79.99
>
> SEARCH.WAITINDEXING products
> SEARCH.QUERY products '{"price":{"$lt":90}}'
> ```

## Hash Documents

For hash indexes, any hash command that modifies a matching key updates the indexed document.

> [tab] TypeScript
>
> ```ts theme={"system"}
> const articles = redis.search.index({ name: "articles" });
>
> await redis.hset("article:1", {
>   status: "published",
>   views: 125,
> });
>
> await articles.waitIndexing();
>
> const published = await articles.query({
>   filter: { status: "published" },
> });
> ```

> [tab] Python
>
> ```python theme={"system"}
> articles = redis.search.index(name="articles")
>
> redis.hset("article:1", values={
>     "status": "published",
>     "views": 125,
> })
>
> articles.wait_indexing()
>
> published = articles.query(filter={"status": "published"})
> ```

> [tab] Redis CLI
>
> ```bash theme={"system"}
> HSET article:1 status published views 125
>
> SEARCH.WAITINDEXING articles
> SEARCH.QUERY articles '{"status":"published"}'
> ```

## String Documents

For string indexes, indexed keys must contain valid JSON strings.
Any command that replaces or modifies the matching string key updates the indexed document.

> [tab] TypeScript
>
> ```ts theme={"system"}
> const notes = redis.search.index({ name: "notes" });
>
> await redis.set("note:1", {
>   title: "Release checklist",
>   status: "done",
> });
>
> await notes.waitIndexing();
>
> const done = await notes.query({
>   filter: { status: "done" },
> });
> ```

> [tab] Python
>
> ```python theme={"system"}
> notes = redis.search.index(name="notes")
>
> redis.set("note:1", '{"title":"Release checklist","status":"done"}')
>
> notes.wait_indexing()
>
> done = notes.query(filter={"status": "done"})
> ```

> [tab] Redis CLI
>
> ```bash theme={"system"}
> SET note:1 '{"title":"Release checklist","status":"done"}'
>
> SEARCH.WAITINDEXING notes
> SEARCH.QUERY notes '{"status":"done"}'
> ```

## Stream Entries

For a stream index, `XADD` adds one document whose ID is the stream entry ID. Commands that remove
entries, including `XDEL` and `XTRIM`, remove the corresponding documents from the index.

```bash theme={"system"}
SEARCH.CREATE event-search ON STREAM events SCHEMA message TEXT severity U64 FAST

XADD events 1-0 message "Payment authorization failed" severity 4

SEARCH.WAITINDEXING event-search
SEARCH.QUERY event-search '{"message":"authorization"}'
```

Deleting or expiring the entire stream clears its documents but keeps the index definition. New
entries are indexed if the stream is later recreated under the same key.

See [Searching Streams](https://upstash.com/docs/redis/search/streams) for stream-specific schema rules and operational
constraints.

## Deletes

Deleting a matching key removes the document from a JSON, hash, or string index. Deleting a stream
removes all of that stream's entry documents from its stream index.

> [tab] TypeScript
>
> ```ts theme={"system"}
> await redis.del("product:1");
> await products.waitIndexing();
> ```

> [tab] Python
>
> ```python theme={"system"}
> redis.delete("product:1")
> products.wait_indexing()
> ```

> [tab] Redis CLI
>
> ```bash theme={"system"}
> DEL product:1
> SEARCH.WAITINDEXING products
> ```

## Expiration

When a matching key expires, Upstash Redis Search removes the expired document from the index.

> [tab] TypeScript
>
> ```ts theme={"system"}
> await redis.expire("product:flash-sale", 3600);
> ```

> [tab] Python
>
> ```python theme={"system"}
> redis.expire("product:flash-sale", 3600)
> ```

> [tab] Redis CLI
>
> ```bash theme={"system"}
> EXPIRE product:flash-sale 3600
> ```

## Eviction

When an indexed key is evicted, Upstash Redis Search removes the document from the index. Once the Redis key is gone,
it no longer appears in search results.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.