> ## 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.

# SEARCH.CREATE

> Create a search index.

Use `SEARCH.CREATE` to create a search index over JSON, hash, or string values, or over a stream.

`ON` names the type of key to index and `PREFIX` the key prefixes to watch, so the index covers exactly the keys that match both, including keys written after it was created. The `SCHEMA` then declares which fields are searchable and how: `TEXT` fields are analyzed for full-text search, with `NOSTEM` and `NOTOKENIZE` to turn parts of that off, numeric, boolean, and date fields are matched exactly and can be marked `FAST` to make them usable for sorting and scoring, and `KEYWORD` and `FACET` fields are kept whole for exact matching and faceting. `FROM` maps a schema field to a differently named field in the document.

`ON STREAM` indexes a single stream instead of a set of keys, so it takes the stream key in place of `PREFIX`. Each entry added with [`XADD`](/docs/redis/commands/streams/xadd) becomes a document whose fields are the entry's fields and whose ID is the entry ID, which is what makes a stream searchable by content rather than only by ID range. Entries removed from the stream leave the index as well.

`TEXT`, `KEYWORD`, `U64`, `I64`, `F64`, and `DATE` fields can index multiple values. Store the field as a JSON array; for hash and stream indexes, store the complete JSON-encoded array in the field string. Each valid element is indexed separately, and a document matches when any element matches. `BOOL` and `FACET` fields remain single-valued.

Creating an index starts an initial scan of the matching keys, which `SKIPINITIALSCAN` skips when you only want to index data written from now on. `EXISTSOK` makes the command succeed instead of failing when the index already exists.

See [Index Management](/docs/redis/search/index-management#creating-an-index) for a feature-level guide to creating indexes and [Schema Definition](/docs/redis/search/schema-definition) for field types and schema design.

> [!NOTE]
>
> Upstash Redis Search uses `SEARCH.*` commands. They are separate from and incompatible with the `FT.*` commands in the open-source RediSearch module.

## Syntax

```redis theme={"system"}
SEARCH.CREATE <name>
  ON <JSON|HASH|STRING> PREFIX <count> <prefix> [<prefix> ...]
  | ON STREAM <stream-key>
  [LANGUAGE <language>]
  [SKIPINITIALSCAN]
  [EXISTSOK]
  SCHEMA
    <field> TEXT [NOSTEM] [NOTOKENIZE] [FROM <source_field>]
    | <field> <U64|I64|F64|BOOL|DATE> [FAST] [FROM <source_field>]
    | <field> <KEYWORD|FACET> [FROM <source_field>]
    [...]
```

## Arguments

| Argument | Description |
| - | - |
| `ON` | Type of Redis value to index: `JSON`, `HASH`, `STRING`, or `STREAM`. A `STRING` value must contain a JSON object. |
| `PREFIX` | One or more key prefixes. Prefixes in the same index cannot be duplicates or overlap one another. Not allowed with `ON STREAM`. |
| `<stream-key>` | Key of the stream to index. Required with `ON STREAM`, and given in place of `PREFIX`. |
| `LANGUAGE` | Stemming language for `TEXT` fields. Defaults to `english`. Supported values are `arabic`, `danish`, `dutch`, `english`, `finnish`, `french`, `german`, `greek`, `hungarian`, `italian`, `norwegian`, `portuguese`, `romanian`, `russian`, `spanish`, `swedish`, `tamil`, and `turkish`. |
| `SKIPINITIALSCAN` | Create the index without scanning existing keys. Later writes are still indexed. |
| `EXISTSOK` | Return `0` when an index with the same data type, prefixes, and schema already exists. A configuration mismatch returns an error. |
| `SCHEMA` | One or more field definitions. `SCHEMA` must be the final top-level clause. |

### Schema field options

| Option | Valid field types | Description |
| - | - | - |
| `FAST` | `U64`, `I64`, `F64`, `BOOL`, `DATE` | Store the field for operations such as sorting and aggregations. Score functions accept `FAST` fields of type `U64`, `I64`, or `F64`. |
| `NOSTEM` | `TEXT` | Index text without stemming words to their roots. |
| `NOTOKENIZE` | `TEXT` | Index the entire value as one token. |
| `FROM <source_field>` | All field types | Read the value from a different document field or nested dot path while exposing it under `<field>` in the index. |

`TEXT`, `KEYWORD`, `U64`, `I64`, `F64`, and `DATE` fields accept multiple values. A field whose value is a JSON array is indexed element by element, and a document matches when any valid element matches. See [Multi-value fields](/docs/redis/search/schema-definition#multi-value-fields) for data-type-specific input formats and query behavior.

## Response

Returns `1` when the index is created. With `EXISTSOK`, returns `0` if the existing index has the same data type, prefixes, and schema. Returns an error for a different configuration or when `<name>` is already used by a non-index Redis key.

## Examples

> **Redis CLI**
>
> ```bash theme={"system"}
> SEARCH.CREATE products ON JSON PREFIX 1 product: SCHEMA name TEXT price F64 FAST inStock BOOL
>
> # Index a stream instead of a set of keys
> SEARCH.CREATE events ON STREAM stream:events SCHEMA message TEXT level KEYWORD
> ```

> **@upstash/redis**
>
> ```ts theme={"system"}
> import { Redis, s } from "@upstash/redis";
>
> const redis = Redis.fromEnv();
>
> const products = await redis.search.createIndex({
>   name: "products",
>   dataType: "json",
>   prefix: "product:",
>   schema: s.object({
>     name: s.string(),
>     price: s.number("F64"),
>     inStock: s.boolean(),
>   }),
> });
> ```

> **upstash\_redis**
>
> ```python theme={"system"}
> from upstash_redis import Redis
>
> redis = Redis.from_env()
>
> products = redis.search.create_index(
>     name="products",
>     data_type="json",
>     prefixes="product:",
>     schema={
>         "name": "TEXT",
>         "price": {"type": "F64", "fast": True},
>         "inStock": "BOOL",
>     },
> )
> ```

> **ioredis**
>
> ```ts theme={"system"}
> import IORedis from "ioredis";
> import { createSearch, s } from "@upstash/search-ioredis";
>
> const redis = new IORedis(process.env.REDIS_URL!);
> const search = createSearch(redis);
>
> const products = await search.createIndex({
>   name: "products",
>   dataType: "json",
>   prefix: "product:",
>   schema: s.object({
>     name: s.string(),
>     price: s.number("F64"),
>     inStock: s.boolean(),
>   }),
> });
> ```

> **node-redis**
>
> ```ts theme={"system"}
> import { createClient } from "redis";
> import { createSearch, s } from "@upstash/search-redis";
>
> const client = await createClient({ url: process.env.REDIS_URL })
>   .on("error", console.error)
>   .connect();
> const search = createSearch(client);
>
> const products = await search.createIndex({
>   name: "products",
>   dataType: "json",
>   prefix: "product:",
>   schema: s.object({
>     name: s.string(),
>     price: s.number("F64"),
>     inStock: s.boolean(),
>   }),
> });
> ```

> **redis-py**
>
> ```python theme={"system"}
> import os
> import redis
>
> client = redis.from_url(os.environ["REDIS_URL"])
> result = client.execute_command(
>     "SEARCH.CREATE",
>     "products",
>     "ON",
>     "JSON",
>     "PREFIX",
>     "1",
>     "product:",
>     "SCHEMA",
>     "name",
>     "TEXT",
>     "price",
>     "F64",
>     "FAST",
>     "inStock",
>     "BOOL",
> )
> print(result)
> ```

> **go-redis**
>
> ```go theme={"system"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "os"
>
>     "github.com/redis/go-redis/v9"
> )
>
> func main() {
>     opts, err := redis.ParseURL(os.Getenv("REDIS_URL"))
>     if err != nil {
>         panic(err)
>     }
>     client := redis.NewClient(opts)
>     result, err := client.Do(
>         context.Background(),
>         "SEARCH.CREATE",
>         "products",
>         "ON",
>         "JSON",
>         "PREFIX",
>         "1",
>         "product:",
>         "SCHEMA",
>         "name",
>         "TEXT",
>         "price",
>         "F64",
>         "FAST",
>         "inStock",
>         "BOOL",
>     ).Result()
>     if err != nil {
>         panic(err)
>     }
>     fmt.Println(result)
> }
> ```

> **jedis**
>
> ```java theme={"system"}
> import java.net.URI;
>
> import redis.clients.jedis.Jedis;
>
> try (Jedis jedis = new Jedis(new URI(System.getenv("REDIS_URL")))) {
>   Object result = jedis.sendCommand(
>       () -> "SEARCH.CREATE".getBytes(),
>       "products",
>       "ON",
>       "JSON",
>       "PREFIX",
>       "1",
>       "product:",
>       "SCHEMA",
>       "name",
>       "TEXT",
>       "price",
>       "F64",
>       "FAST",
>       "inStock",
>       "BOOL"
>   );
>   System.out.println(result);
> }
> ```

> **redis-rs**
>
> ```rust theme={"system"}
> fn main() -> redis::RedisResult<()> {
>     let url = std::env::var("REDIS_URL").expect("REDIS_URL is not set");
>     let client = redis::Client::open(url)?;
>     let mut connection = client.get_connection()?;
>
>     let mut command = redis::cmd("SEARCH.CREATE");
>     command.arg("products");
>     command.arg("ON");
>     command.arg("JSON");
>     command.arg("PREFIX");
>     command.arg("1");
>     command.arg("product:");
>     command.arg("SCHEMA");
>     command.arg("name");
>     command.arg("TEXT");
>     command.arg("price");
>     command.arg("F64");
>     command.arg("FAST");
>     command.arg("inStock");
>     command.arg("BOOL");
>     let result: redis::Value = command.query(&mut connection)?;
>     println!("{result:?}");
>     Ok(())
> }
> ```

> **curl**
>
> ```bash theme={"system"}
> curl -X POST https://YOUR_ENDPOINT.upstash.io \
>   -H "Authorization: Bearer $UPSTASH_REDIS_REST_TOKEN" \
>   -d '["SEARCH.CREATE", "products", "ON", "JSON", "PREFIX", "1", "product:", "SCHEMA", "name", "TEXT", "price", "F64", "FAST", "inStock", "BOOL"]'
> ```


## Related topics

- [Blog Search](/docs/redis/search/recipes/blog-search.md)
- [E-commerce Search](/docs/redis/search/recipes/e-commerce-search.md)
- [Searching Streams](/docs/redis/search/streams.md)
- [Aliases](/docs/redis/search/aliases.md)
- [Schemas](/docs/redis/search/schema-definition.md)


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