{
  "schema_version": 2,
  "id": "commands/ft.search",
  "title": "FT.SEARCH",
  "url": "https://redis.io/docs/latest/commands/ft.search/",
  "summary": "Searches the index with a textual query, returning either documents or just ids",
  "since": "1.0.0",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-18T09:47:58+01:00",
  "page_type": "content",
  "content_hash": "2568ba11954639d0163804175a0585ad2ad36c411ed608fc5d32d0fd3236cac9",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Search the index with a textual query, returning either documents or just ids.\n\n> [!NOTE]\n> This command will only return keys to which the user has read access.\n\n[Examples](#examples)"
    },
    {
      "id": "required-arguments",
      "title": "Required arguments",
      "role": "content",
      "text": "<details open>\n<summary><code>index</code></summary>\n\nis index name. You must first create the index using [`FT.CREATE`](https://redis.io/docs/latest/commands/ft.create).\n</details>\n\n<details open>\n<summary><code>query</code></summary> \n\nis text query to search. If it's more than a single word, put it in quotes. Refer to [Query syntax](https://redis.io/docs/latest/develop/ai/search-and-query/query) for more details.\n</details>"
    },
    {
      "id": "optional-arguments",
      "title": "Optional arguments",
      "role": "parameters",
      "text": "<details open>\n<summary><code>NOCONTENT</code></summary>\n\nreturns the document ids and not the content. This is useful if RediSearch is only an index on an external document collection.\n</details>\n\n<details open>\n<summary><code>VERBATIM</code></summary>\n\ndoes not try to use stemming for query expansion but searches the query terms verbatim.\n</details>\n\n<details open>\n<summary><code>NOSTOPWORDS (deprecated)</code></summary>\n\nignores any defined stop words in full text searches. Note: this option is deprecated as of Redis 8.0.\n</details>\n\n<details open>\n<summary><code>WITHSCORES</code></summary>\n\nalso returns the relative internal score of each document. This can be used to merge results from multiple instances.\n</details>\n\n<details open>\n<summary><code>WITHPAYLOADS</code></summary>\n\nretrieves optional document payloads. See [`FT.CREATE`](https://redis.io/docs/latest/commands/ft.create). The payloads follow the document id and, if `WITHSCORES` is set, the scores.\n</details>\n\n<details open>\n<summary><code>WITHSORTKEYS</code></summary>\n\nreturns the value of the sorting key, right after the id and score and/or payload, if requested. This is usually not needed, and exists for distributed search coordination purposes. This option is relevant only if used in conjunction with `SORTBY`.\n</details>\n\n<details open>\n<summary><code>FILTER numeric_attribute min max</code></summary>\n\nlimits results to those having numeric values ranging between `min` and `max`, if numeric_attribute is defined as a numeric attribute in [`FT.CREATE`](https://redis.io/docs/latest/commands/ft.create). \n  `min` and `max` follow [`ZRANGE`](https://redis.io/docs/latest/commands/zrange) syntax, and can be `-inf`, `+inf`, and use `(` for exclusive ranges. Multiple numeric filters for different attributes are supported in one query.\n**Deprecated since v2.10**: [Query dialect 2](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/dialects#dialect-2) explains the query syntax for numeric fields that replaces this argument.\n</details>\n\n<details open>\n<summary><code>GEOFILTER {geo_attribute} {lon} {lat} {radius} m|km|mi|ft</code></summary>\n\nfilter the results to a given `radius` from `lon` and `lat`. Radius is given as a number and units. See [`GEORADIUS`](https://redis.io/docs/latest/commands/georadius) for more details.\n**Deprecated since v2.6**: [Query dialect 3](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/dialects#dialect-3) explains the query syntax for geospatial fields that replaces this argument.\n</details>\n\n<details open>\n<summary><code>INKEYS {num} {attribute} ...</code></summary>\n\nlimits the result to a given set of keys specified in the list. The first argument must be the length of the list and greater than zero. Non-existent keys are ignored, unless all the keys are non-existent.\n</details>\n\n<details open>\n<summary><code>INFIELDS {num} {attribute} ...</code></summary>\n\nfilters the results to those appearing only in specific attributes of the document, like `title` or `URL`. You must include `num`, which is the number of attributes you're filtering by. For example, if you request `title` and `URL`, then `num` is 2.\n</details>\n\n<details open>\n<summary><code>RETURN {num} {identifier} AS {property} ...</code></summary>\n\nlimits the attributes returned from the document. `num` is the number of attributes following the keyword. If `num` is 0, it acts like `NOCONTENT`.\n  `identifier` is either an attribute name (for hashes and JSON) or a JSON Path expression (for JSON).\n  `property` is an optional name used in the result. If not provided, the `identifier` is used in the result.\n</details>\n\n<details open>\n<summary><code>SUMMARIZE ...</code></summary>\n\nreturns only the sections of the attribute that contain the matched text. See [Highlighting](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/highlight) for more information.\n</details>\n\n<details open>\n<summary><code>HIGHLIGHT ...</code></summary>\n\nformats occurrences of matched text. See [Highlighting](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/highlight) for more information.\n</details>\n\n<details open>\n<summary><code>SLOP {slop}</code></summary>\n\nis the number of intermediate terms allowed to appear between the terms of the query. \nSuppose you're searching for a phrase _hello world_.\nIf some terms appear in-between _hello_ and _world_, a `SLOP` greater than `0` allows for these text attributes to match.\nBy default, there is no `SLOP` constraint.\n</details>\n\n<details open>\n<summary><code>INORDER</code></summary>\n\nrequires the terms in the document to have the same order as the terms in the query, regardless of the offsets between them. Typically used in conjunction with `SLOP`. Default is `false`.\n\n</details>\n\n<details open>\n<summary><code>LANGUAGE {language}</code></summary>\n\nuse a stemmer for the supplied language during search for query expansion. If querying documents in Chinese, set to `chinese` to\n  properly tokenize the query terms. Defaults to English. If an unsupported language is sent, the command returns an error.\n  See [`FT.CREATE`](https://redis.io/docs/latest/commands/ft.create) for the list of languages. If `LANGUAGE` was specified as part of index\n  creation, it doesn't need to specified with `FT.SEARCH`.\n</details>\n\n<details open>\n<summary><code>EXPANDER {expander}</code></summary>\n\nuses a custom query expander instead of the stemmer. See [Extensions](https://redis.io/docs/latest/develop/ai/search-and-query/administration/extensions).\n</details>\n\n<details open>\n<summary><code>SCORER {scorer}</code></summary>\n\nuses a [built-in](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/scoring) or a [user-provided](https://redis.io/docs/latest/develop/ai/search-and-query/administration/extensions) scoring function.\n</details>\n\n<details open>\n<summary><code>EXPLAINSCORE</code></summary>\n\nreturns a textual description of how the scores were calculated. Using this option requires `WITHSCORES`.\n</details>\n\n<details open>\n<summary><code>PAYLOAD {payload}</code></summary>\n\nadds an arbitrary, binary safe payload that is exposed to custom scoring functions. See [Extensions](https://redis.io/docs/latest/develop/ai/search-and-query/administration/extensions).\n</details>\n\n<details open>\n<summary><code>SORTBY {attribute} [ASC|DESC] [WITHCOUNT]</code></summary>\n\norders the results by the value of this attribute. This applies to both text and numeric attributes. Attributes needed for `SORTBY` should be declared as `SORTABLE` in the index, in order to be available with very low latency. Note that this adds memory overhead.\n\n**Sorting Optimizations**: performance is optimized for sorting operations on `DIALECT 4` in different scenarios:\n  - Skip Sorter - applied when there is no sort of any kind. The query can return after it reaches the `LIMIT` requested results.\n  - Partial Range - applied when there is a `SORTBY` clause over a numeric field, with no filter or filter by the same numeric field, the query iterate on a range large enough to satisfy the `LIMIT` requested results.\n  - Hybrid - applied when there is a `SORTBY` clause over a numeric field and another non-numeric filter. Some results will get filtered, and the initial range may not be large enough. The iterator is then rewinding with the following ranges, and an additional iteration takes place to collect the `LIMIT` requested results.\n  - No optimization - If there is a sort by score or by non-numeric field, there is no other option but to retrieve all results and compare their values.\n\n**Counts behavior**: optional `WITHCOUNT` argument returns accurate counts for the query results with sorting. This operation processes all results in order to get an accurate count, being less performant than the optimized option (default behavior on `DIALECT 4`)\n\nYou can also use `WITHOUTCOUNT` in place of `DIALECT 4` when used with either `FT.SEARCH` or `FT.AGGREGATE`.\n</details>\n\n<details open>\n<summary><code>LIMIT first num</code></summary>\n\nlimits the results to the offset and number of results given. Note that the offset is zero-indexed. The default is 0 10, which returns 10 items starting from the first result. You can use `LIMIT 0 0` to count the number of documents in the result set without actually returning them.\n\n**`LIMIT` behavior**:  If you use the `LIMIT` option without sorting, the results returned are non-deterministic, which means that subsequent queries may return duplicated or missing values. Add `SORTBY` with a unique field, or use `FT.AGGREGATE` with the `WITHCURSOR` option to ensure deterministic result set paging.\n</details>\n\n<details open>\n<summary><code>TIMEOUT {milliseconds}</code></summary>\n\noverrides the timeout parameter of the module.\n</details>\n\n<details open>\n<summary><code>PARAMS {nargs} {name} {value}</code></summary>\n\ndefines one or more value parameters. Each parameter has a name and a value. \n\nYou can reference parameters in the `query` by a `$`, followed by the parameter name, for example, `$user`. Each such reference in the search query to a parameter name is substituted by the corresponding parameter value. For example, with parameter definition `PARAMS 4 lon 29.69465 lat 34.95126`, the expression `@loc:[$lon $lat 10 km]` is evaluated to `@loc:[29.69465 34.95126 10 km]`. You cannot reference parameters in the query string where concrete values are not allowed, such as in field names, for example, `@loc`. To use `PARAMS`, set\n[`DIALECT`](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/dialects#dialect-2)\nto `2` or greater than `2` (this requires [RediSearch v2.4](https://github.com/RediSearch/RediSearch/releases/tag/v2.4.3) or above).\n</details>\n\n<details open>\n<summary><code>DIALECT {dialect_version}</code></summary>\n\nselects the dialect version under which to execute the query. If not specified, the query will execute under the default dialect version set during module initial loading or via [`FT.CONFIG SET`](https://redis.io/docs/latest/commands/ft.config-set) command. See [Query dialects](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/dialects) for more information.\n</details>"
    },
    {
      "id": "return",
      "title": "Return",
      "role": "returns",
      "text": "FT.SEARCH returns an array reply. The first element is an integer reply that contains the total number of documents that match the query. The remaining elements are pairs: a document ID followed by an array of attribute-value pairs.\n\nThis total is not necessarily the number of documents returned in the reply. `LIMIT` controls how many matching documents follow the count. It defaults to `0 10`, so a query with more than 10 matching documents returns a count greater than the number of returned documents. Use `LIMIT 0 0` to get only the total.\n\nFor example, if 42 documents match the query, the count is 42, even though the reply returns only the first 10 documents:\n\n[code example]\n\n> [!NOTE]\n>  \n> - If you specify `NOCONTENT`, the command returns an array where the first element is the total number of matching documents and the remaining elements are document IDs.\n> - If a matching key expires or is updated while a query is running, Redis returns a null array when it tries to load the updated key's value. The key still counts as a matching document.\n> - The number of matching documents is accurate unless the query uses the sorting optimizations of `DIALECT 4` or `WITHOUTCOUNT`. These queries stop as soon as they collect the results requested by `LIMIT`, so the reported number is capped at the size of the `LIMIT` window instead of counting every matching document. Add `WITHCOUNT` to a `SORTBY` clause to get an accurate count."
    },
    {
      "id": "return-multiple-values",
      "title": "Return multiple values",
      "role": "returns",
      "text": "When the index is defined `ON JSON`, a reply for a single attribute or a single JSONPath may return multiple values when the JSONPath matches multiple values, or when the JSONPath matches an array.\n\nPrior to RediSearch v2.6, only the first of the matched values was returned.\nStarting with RediSearch v2.6, all values are returned, wrapped with a top-level array.\n\nIn order to maintain backward compatibility, the default behavior with RediSearch v2.6 is to return only the first value.\n\nTo return all the values, use `DIALECT` 3 (or greater, when available).\n\nThe `DIALECT` can be specified as a parameter in the FT.SEARCH command. If it is not specified, the `DEFAULT_DIALECT` is used, which can be set using [`FT.CONFIG SET`](https://redis.io/docs/latest/commands/ft.config-set) or by passing it as an argument to the `redisearch` module when it is loaded.\n\nFor example, with the following document and index:\n\n[code example]\nNotice the different replies, with and without `DIALECT 3`:\n\n[code example]"
    },
    {
      "id": "complexity",
      "title": "Complexity",
      "role": "performance",
      "text": "FT.SEARCH complexity is O(n) for single word queries. `n` is the number of the results in the result set. Finding all the documents that have a specific term is O(1), however, a scan on all those documents is needed to load the documents data from redis hashes and return them.\n\nThe time complexity for more complex queries varies, but in general it's proportional to the number of words, the number of intersection points between them and the number of results in the result set."
    },
    {
      "id": "examples",
      "title": "Examples",
      "role": "example",
      "text": "<details open>\n<summary><b>Search for a term in every text attribute</b></summary>\n\nSearch for the term \"wizard\" in every TEXT attribute of an index containing book data.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"wizard\"\n\n</details>\n\n<details open>\n<summary><b>Search for a term in title attribute</b></summary>\n\nSearch for the term _dogs_ in the `title` attribute.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"@title:dogs\"\n\n</details>\n\n<details open>\n<summary><b>Search for books from specific years</b></summary>\n\nSearch for books published in 2020 or 2021.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"@published_at:[2020 2021]\"\n\n</details>\n\n<details open>\n<summary><b>Search for a restaurant by distance from longitude/latitude</b></summary>\n\nSearch for Chinese restaurants within 5 kilometers of longitude -122.41, latitude 37.77 (San Francisco).\n\n\n127.0.0.1:6379> FT.SEARCH restaurants-idx \"chinese @location:[-122.41 37.77 5 km]\"\n\n</details>\n\n<details open>\n<summary><b>Search for a book by terms but boost specific term</b></summary>\n\nSearch for the term _dogs_ or _cats_ in the `title` attribute, but give matches of _dogs_ a higher relevance score (also known as _boosting_).\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"(@title:dogs | @title:cats) | (@title:dogs) => { $weight: 5.0; }\"\n\n</details>\n\n<details open>\n<summary><b>Search for a book by a term and EXPLAINSCORE</b></summary>\n\nSearch for books with _dogs_ in any TEXT attribute in the index and request an explanation of scoring for each result.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"dogs\" WITHSCORES EXPLAINSCORE\n\n</details>\n\n<details open>\n<summary><b>Search for a book by a term and TAG</b></summary>\n\nSearch for books with _space_ in the title that have `science` in the TAG attribute `categories`.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"@title:space @categories:{science}\"\n\n</details>\n\n<details open>\n<summary><b>Search for a book by a term but limit the number</b></summary>\n\nSearch for books with _Python_ in any `TEXT` attribute, returning 10 results starting with the 11th result in the entire result set (the offset parameter is zero-based), and return only the `title` attribute for each result.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"python\" LIMIT 10 10 RETURN 1 title\n\n</details>\n\n<details open>\n<summary><b>Search for a book by a term and price</b></summary>\n\nSearch for books with _Python_ in any `TEXT` attribute, returning the price stored in the original JSON document.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"python\" RETURN 3 $.book.price AS price\n\n</details>\n\n<details open>\n<summary><b>Search for a book by title and distance</b></summary>\n\nSearch for books with semantically similar title to _Planet Earth_. Return top 10 results sorted by distance.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"*=>[KNN 10 @title_embedding $query_vec AS title_score]\" PARAMS 2 query_vec <\"Planet Earth\" embedding BLOB> SORTBY title_score DIALECT 2\n\n</details>\n\n<details open>\n<summary><b>Vector search with cluster optimization</b></summary>\n\nSearch for books with titles that are semantically similar to _Planet Earth_ using cluster optimization. Each shard retrieves 60% of the requested results for improved performance in Redis cluster environments. See the [query attributes](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/query_attributes) reference page for more information.\n\n\n127.0.0.1:6379> FT.SEARCH books-idx \"*=>[KNN 100 @title_embedding $query_vec]=>{$SHARD_K_RATIO: 0.6; $YIELD_DISTANCE_AS: title_score}\" PARAMS 2 query_vec <\"Planet Earth\" embedding BLOB> SORTBY title_score DIALECT 2\n\n</details>\n\n<details open>\n<summary><b>Search for a phrase using SLOP</b></summary>\n\nSearch for a phrase _hello world_.\nFirst, create an index.\n\n\n127.0.0.1:6379> FT.CREATE memes SCHEMA phrase TEXT\nOK\n\n\nAdd variations of the phrase _hello world_.\n\n\n127.0.0.1:6379> HSET s1 phrase \"hello world\"\n(integer) 1\n127.0.0.1:6379> HSET s2 phrase \"hello simple world\"\n(integer) 1\n127.0.0.1:6379> HSET s3 phrase \"hello somewhat less simple world\"\n(integer) 1\n127.0.0.1:6379> HSET s4 phrase \"hello complicated yet encouraging problem solving world\"\n(integer) 1\n127.0.0.1:6379> HSET s5 phrase \"hello complicated yet amazingly encouraging problem solving world\"\n(integer) 1\n\n\nThen, search for the phrase _hello world_. The result returns all documents that contain the phrase.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT \n1) (integer) 5\n2) \"s1\"\n3) \"s2\"\n4) \"s3\"\n5) \"s4\"\n6) \"s5\"\n\n\nNow, return all documents that have one of fewer words between _hello_ and _world_.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 1\n1) (integer) 2\n2) \"s1\"\n3) \"s2\"\n\n\nNow, return all documents with three or fewer words between _hello_ and _world_.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 3\n1) (integer) 3\n2) \"s1\"\n3) \"s2\"\n4) \"s3\"\n\n\n`s5` needs a higher `SLOP` to match, `SLOP 6` or higher, to be exact. See what happens when you set `SLOP` to `5`.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello world)' NOCONTENT SLOP 5\n1) (integer) 4\n2) \"s1\"\n3) \"s2\"\n4) \"s3\"\n5) \"s4\"\n\n\nIf you add additional terms (and stemming), you get these results.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello amazing world)' NOCONTENT \n1) (integer) 1\n2) \"s5\"\n\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello encouraged world)' NOCONTENT SLOP 5\n1) (integer) 2\n2) \"s4\"\n3) \"s5\"\n\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(hello encouraged world)' NOCONTENT SLOP 4\n1) (integer) 1\n2) \"s4\"\n\n\nIf you swap the terms, you can still retrieve the correct phrase.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT\n1) (integer) 1\n2) \"s5\"\n\n\nBut, if you use `INORDER`, you get zero results.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)' NOCONTENT INORDER\n1) (integer) 0\n\n\nLikewise, if you use a query attribute `$inorder` set to `true`, `s5` is not retrieved.\n\n\n127.0.0.1:6379> FT.SEARCH memes '@phrase:(amazing hello world)=>{$inorder: true;}' NOCONTENT\n1) (integer) 0\n\n\nTo sum up, the `INORDER` argument or `$inorder` query attribute require the query terms to match terms with similar ordering.\n\n</details>\n\n<details open>\n<summary><b>Polygon Search with WITHIN, CONTAINS, INTERSECTS, and DISJOINT operators</b></summary>\n\nQuery for polygons which:\n\n- contain a given geoshape\n- are within a given geoshape\n- intersect with a given geoshape\n- are disjoint (nothing in common) with a given shape\n\n`INTERSECTS` and `DISJOINT` were introduced in v2.10.\n\nFirst, create an index using `GEOSHAPE` type with a `FLAT` coordinate system:\n\n\n127.0.0.1:6379> FT.CREATE idx SCHEMA geom GEOSHAPE FLAT\nOK\n\n\nAdding a couple of geometries using [`HSET`](https://redis.io/docs/latest/commands/hset):\n\n\n127.0.0.1:6379> HSET small geom 'POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))'\n(integer) 1\n127.0.0.1:6379> HSET large geom 'POLYGON((1 1, 1 200, 200 200, 200 1, 1 1))'\n(integer) 1\n\n\nQuery with `WITHIN` operator:\n\n\n127.0.0.1:6379> FT.SEARCH idx '@geom:[WITHIN $poly]' PARAMS 2 poly 'POLYGON((0 0, 0 150, 150 150, 150 0, 0 0))' DIALECT 3\n\n1) (integer) 1\n2) \"small\"\n3) 1) \"geom\"\n   2) \"POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))\"\n\n\nQuery with `CONTAINS` operator:\n\n\n127.0.0.1:6379> FT.SEARCH idx '@geom:[CONTAINS $poly]' PARAMS 2 poly 'POLYGON((2 2, 2 50, 50 50, 50 2, 2 2))' DIALECT 3\n\n1) (integer) 2\n2) \"small\"\n3) 1) \"geom\"\n   2) \"POLYGON((1 1, 1 100, 100 100, 100 1, 1 1))\"\n4) \"large\"\n5) 1) \"geom\"\n   2) \"POLYGON((1 1, 1 200, 200 200, 200 1, 1 1))\"\n\n\n</details>"
    },
    {
      "id": "redis-software-and-redis-cloud-compatibility",
      "title": "Redis Software and Redis Cloud compatibility",
      "role": "content",
      "text": "| Redis<br />Software | Redis Cloud<br />Flexible & Annual | Redis Cloud<br />Free & Fixed | <span style=\"min-width: 9em; display: table-cell\">Notes</span> |\n|:----------------------|:-----------------|:-----------------|:------|\n| <span title=\"Supported\">&#x2705; Supported</span> | <span title=\"Supported\">&#x2705; Supported</span> | <span title=\"Supported\">&#x2705; Supported</nobr></span> |  |"
    },
    {
      "id": "return-information",
      "title": "Return information",
      "role": "returns",
      "text": "**RESP2:**\n\nOne of the following:\n* [Array](https://redis.io/docs/latest/develop/reference/protocol-spec#arrays): the first element is the total number of documents that match the query. The remaining elements are document IDs followed by their field-value pairs as [arrays](https://redis.io/docs/latest/develop/reference/protocol-spec#arrays). The number of documents returned in the reply is limited by `LIMIT`, so it is often smaller than the total number of matching documents.\n* [Simple error reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-errors) in these cases: no such index, syntax error in query.\n\n**RESP3:**\n\nOne of the following:\n* [Map](https://redis.io/docs/latest/develop/reference/protocol-spec#maps) with the following fields:\n    - `total_results`: [Integer](https://redis.io/docs/latest/develop/reference/protocol-spec#integers) - the total number of documents that match the query, regardless of how many are returned in `results`\n    - `results`: [Array](https://redis.io/docs/latest/develop/reference/protocol-spec#arrays) of [maps](https://redis.io/docs/latest/develop/reference/protocol-spec#maps) containing document information, limited by `LIMIT`\n    - `attributes`: [Array](https://redis.io/docs/latest/develop/reference/protocol-spec#arrays) of attribute names\n    - `format`: [Simple string](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-strings) - result format\n    - `warning`: [Array](https://redis.io/docs/latest/develop/reference/protocol-spec#arrays) of warning messages\n* [Simple error reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-errors) in these cases: no such index, syntax error in query."
    },
    {
      "id": "see-also",
      "title": "See also",
      "role": "related",
      "text": "[`FT.CREATE`](https://redis.io/docs/latest/commands/ft.create) | [`FT.AGGREGATE`](https://redis.io/docs/latest/commands/ft.aggregate)"
    },
    {
      "id": "related-topics",
      "title": "Related topics",
      "role": "related",
      "text": "- [Extensions](https://redis.io/docs/latest/develop/ai/search-and-query/administration/extensions)\n- [Highlighting](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/highlight)\n- [Key and field expiration behavior](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/expiration)\n- [Query syntax](https://redis.io/docs/latest/develop/ai/search-and-query/query)\n- [RediSearch](https://redis.io/docs/latest/develop/ai/search-and-query)\n- [Search commands in MULTI/EXEC transactions and Lua scripts](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/transactions)"
    }
  ],
  "examples": [
    {
      "id": "return-ex0",
      "language": "sh",
      "code": "127.0.0.1:6379> FT.SEARCH idx \"@title:redis\" NOCONTENT\n 1) (integer) 42\n 2) \"doc:1\"\n 3) \"doc:2\"\n...\n11) \"doc:10\"\n\n127.0.0.1:6379> FT.SEARCH idx \"@title:redis\" LIMIT 0 0\n1) (integer) 42",
      "section_id": "return"
    },
    {
      "id": "return-multiple-values-ex0",
      "language": "sh",
      "code": "127.0.0.1:6379> JSON.SET doc:1 $ '[{\"arr\": [1, 2, 3]}, {\"val\": \"hello\"}, {\"val\": \"world\"}]'\nOK\n127.0.0.1:6379> FT.CREATE idx ON JSON PREFIX 1 doc: SCHEMA $..arr AS arr NUMERIC $..val AS val TEXT\nOK",
      "section_id": "return-multiple-values"
    },
    {
      "id": "return-multiple-values-ex1",
      "language": "sh",
      "code": "127.0.0.1:6379> FT.SEARCH idx * RETURN 2 arr val\n1) (integer) 1\n2) \"doc:1\"\n3) 1) \"arr\"\n   2) \"[1,2,3]\"\n   3) \"val\"\n   4) \"hello\"\n\n127.0.0.1:6379> FT.SEARCH idx * RETURN 2 arr val DIALECT 3\n1) (integer) 1\n2) \"doc:1\"\n3) 1) \"arr\"\n   2) \"[[1,2,3]]\"\n   3) \"val\"\n   4) \"[\\\"hello\\\",\\\"world\\\"]\"",
      "section_id": "return-multiple-values"
    }
  ]
}
