1# RediSearch Full Command Documentation 2 3## FT.CREATE 4 5### Format 6``` 7 FT.CREATE {index} 8 [MAXTEXTFIELDS] [TEMPORARY {seconds}] [NOOFFSETS] [NOHL] [NOFIELDS] [NOFREQS] 9 [STOPWORDS {num} {stopword} ...] 10 SCHEMA {field} [TEXT [NOSTEM] [WEIGHT {weight}] [PHONETIC {matcher}] | NUMERIC | GEO | TAG [SEPARATOR {sep}] ] [SORTABLE][NOINDEX] ... 11``` 12 13### Description 14Creates an index with the given spec. The index name will be used in all the key names so keep it short! 15 16!!! warning "Note on field number limits" 17 18 RediSearch supports up to 1024 fields per schema, out of which at most 128 can be TEXT fields. 19 20 On 32 bit builds, at most 64 fields can be TEXT fields. 21 22 Note that the more fields you have, the larger your index will be, as each additional 8 fields require one extra byte per index record to encode. 23 24 You can always use the `NOFIELDS` option and not encode field information into the index, for saving space, if you do not need filtering by text fields. This will still allow filtering by numeric and geo fields. 25 26!!! info "Note on running in clustered databases" 27 28 When having several indices in a clustered database, you need to tag the index key and the document key to ensure they reside on the same shard. 29 30 ``` 31 FT.CREATE {idx} ... 32 FT.ADD {idx} {idx}:docid ... 33 ``` 34 35 When Running in RediSearch in Redis Enterprise, there is the ability to span the index across shards. In this case the above does not apply. 36 37#### Example 38```sql 39FT.CREATE idx SCHEMA name TEXT SORTABLE age NUMERIC SORTABLE myTag TAG SORTABLE 40``` 41 42### Parameters 43 44* **index**: the index name to create. If it exists the old spec will be overwritten 45 46* **MAXTEXTFIELDS**: For efficiency, RediSearch encodes indexes differently if they are 47 created with less than 32 text fields. This option forces RediSearch to encode indexes as if 48 there were more than 32 text fields, which allows you to add additional fields (beyond 32) 49 using `FT.ALTER`. 50 51* **NOOFFSETS**: If set, we do not store term offsets for documents (saves memory, does not 52 allow exact searches or highlighting). Implies `NOHL`. 53 54* **TEMPORARY**: Create a lightweight temporary index which will expire after the specified period of inactivity. The internal idle timer is reset whenever the index is searched or added to. Because such indexes are lightweight, you can create thousands of such indexes without negative performance implications. 55 56* **NOHL**: Conserves storage space and memory by disabling highlighting support. If set, we do 57 not store corresponding byte offsets for term positions. `NOHL` is also implied by `NOOFFSETS`. 58 59* **NOFIELDS**: If set, we do not store field bits for each term. Saves memory, does not allow 60 filtering by specific fields. 61 62* **NOFREQS**: If set, we avoid saving the term frequencies in the index. This saves 63 memory but does not allow sorting based on the frequencies of a given term within 64 the document. 65 66* **STOPWORDS**: If set, we set the index with a custom stopword list, to be ignored during 67 indexing and search time. {num} is the number of stopwords, followed by a list of stopword 68 arguments exactly the length of {num}. 69 70 If not set, we take the default list of stopwords. 71 72 If **{num}** is set to 0, the index will not have stopwords. 73 74* **SCHEMA {field} {options...}**: After the SCHEMA keyword we define the index fields. They 75 can be numeric, textual or geographical. For textual fields we optionally specify a weight. 76 The default weight is 1.0. 77 78 ### Field Options 79 80 81 * **SORTABLE** 82 83 Numeric, tag or text field can have the optional SORTABLE argument that allows the user to later [sort the results by the value of this field](Sorting.md) (this adds memory overhead so do not declare it on large text fields). 84 85 * **NOSTEM** 86 87 Text fields can have the NOSTEM argument which will disable stemming when indexing its values. 88 This may be ideal for things like proper names. 89 90 * **NOINDEX** 91 92 Fields can have the `NOINDEX` option, which means they will not be indexed. 93 This is useful in conjunction with `SORTABLE`, to create fields whose update using PARTIAL will not cause full reindexing of the document. If a field has NOINDEX and doesn't have SORTABLE, it will just be ignored by the index. 94 95 * **PHONETIC {matcher}** 96 97 Declaring a text field as `PHONETIC` will perform phonetic matching on it in searches by default. The obligatory {matcher} argument specifies the phonetic algorithm and language used. The following matchers are supported: 98 99 * `dm:en` - Double Metaphone for English 100 * `dm:fr` - Double Metaphone for French 101 * `dm:pt` - Double Metaphone for Portuguese 102 * `dm:es` - Double Metaphone for Spanish 103 104 For more details see [Phonetic Matching](Phonetic_Matching.md). 105 106 * **WEIGHT {weight}** 107 108 For `TEXT` fields, declares the importance of this field when 109 calculating result accuracy. This is a multiplication factor, and 110 defaults to 1 if not specified. 111 112 * **SEPARATOR {sep}** 113 114 For `TAG` fields, indicates how the text contained in the field 115 is to be split into individual tags. The default is `,`. The value 116 must be a single character. 117 118 119 120### Complexity 121O(1) 122 123### Returns 124OK or an error 125 126--- 127 128## FT.ADD 129 130### Format 131 132``` 133FT.ADD {index} {docId} {score} 134 [NOSAVE] 135 [REPLACE [PARTIAL] [NOCREATE]] 136 [LANGUAGE {language}] 137 [PAYLOAD {payload}] 138 [IF {condition}] 139 FIELDS {field} {value} [{field} {value}...] 140``` 141 142### Description 143 144Adds a document to the index. 145 146#### Example 147```sql 148FT.ADD idx doc1 1.0 FIELDS title "hello world" 149``` 150 151### Parameters 152 153- **index**: The Fulltext index name. The index must be first created with FT.CREATE 154 155- **docId**: The document's id that will be returned from searches. 156 157!!! note "Notes on docId" 158 159 The same docId cannot be added twice to the same index. 160 161 The same docId can be added to multiple indices, but a single document with that docId is saved in the database. 162 163- **score**: The document's rank based on the user's ranking. This must be between 0.0 and 1.0. 164 If you don't have a score just set it to 1 165 166- **NOSAVE**: If set to true, we will not save the actual document in the database and only index it. 167 168- **REPLACE**: If set, we will do an UPSERT style insertion - and delete an older version of the 169 document if it exists. 170 171- **PARTIAL** (only applicable with REPLACE): If set, you do not have to specify all fields for 172 reindexing. Fields not given to the command will be loaded from the current version of the 173 document. Also, if only non-indexable fields, score or payload are set - we do not do a full 174 re-indexing of the document, and this will be a lot faster. 175 176- **NOCREATE** (only applicable with REPLACE): If set, the document is only updated 177 and reindexed if it already exists. If the document does not exist, an error 178 will be returned. 179 180- **FIELDS**: Following the FIELDS specifier, we are looking for pairs of `{field} {value}` to be 181 indexed. Each field will be scored based on the index spec given in `FT.CREATE`. 182 Passing fields that are not in the index spec will make them be stored as part of the document, 183 or ignored if NOSAVE is set 184 185- **PAYLOAD {payload}**: Optionally set a binary safe payload string to the document, 186 that can be evaluated at query time by a custom scoring function, or retrieved to the client. 187 188- **IF {condition}**: (Applicable only in conjunction with `REPLACE` and optionally `PARTIAL`). 189 Update the document only if a boolean expression applies to the document **before the update**, 190 e.g. `FT.ADD idx doc 1 REPLACE IF "@timestamp < 23323234234"`. 191 192 The expression is evaluated atomically before the update, ensuring that the update will happen only if it is true. 193 194 See [Aggregations](Aggregations.md) for more details on the expression language. 195 196- **LANGUAGE language**: If set, we use a stemmer for the supplied language during indexing. Default 197 to English. 198 If an unsupported language is sent, the command returns an error. 199 The supported languages are: 200 201 > "arabic", "danish", "dutch", "english", "finnish", "french", 202 > "german", "hungarian", "italian", "norwegian", "portuguese", "romanian", 203 > "russian", "spanish", "swedish", "tamil", "turkish" 204 > "chinese" 205 206 If indexing a Chinese language document, you must set the language to `chinese` 207 in order for Chinese characters to be tokenized properly. 208 209### Adding Chinese Documents 210 211When adding Chinese-language documents, `LANGUAGE chinese` should be set in 212order for the indexer to properly tokenize the terms. If the default language 213is used then search terms will be extracted based on punctuation characters and 214whitespace. The Chinese language tokenizer makes use of a segmentation algorithm 215(via [Friso](https://github.com/lionsoul2014/friso)) which segments texts and 216checks it against a predefined dictionary. See [Stemming](Stemming.md) for more 217information. 218 219### Complexity 220 221O(n), where n is the number of tokens in the document 222 223### Returns 224 225OK on success, or an error if something went wrong. 226 227A special status `NOADD` is returned if an `IF` condition evaluated to false. 228 229!!! warning "FT.ADD with REPLACE and PARTIAL" 230 231 By default, FT.ADD does not allow updating the document, and will fail if it already exists in the index. 232 233 However, updating the document is possible with the REPLACE and REPLACE PARTIAL options. 234 235 **REPLACE**: On its own, sets the document to the new values, and reindexes it. Any fields not given will not be loaded from the current version of the document. 236 237 **REPLACE PARTIAL**: When both arguments are used, we can update just part of the document fields, and the rest will be loaded before reindexing. Not only that, but if only the score, payload and non-indexed fields (using NOINDEX) are updated, we will not actually reindex the document, just update its metadata internally, which is a lot faster and does not create index garbage. 238 239--- 240 241### Warning!!! 242 243FT.ADD will actually create a hash in Redis with the given fields and value. This means that if the hash already exists, it will override with the new values. Moreover, if you try to add a document with the same id to two different indexes one of them will override the other and you will get wrong responses from one of the indexes. 244For this reason, it is recommended to create global unique documents ids (this can e.g. be achieved by adding the index name to the document id as prefix). 245 246## FT.ADDHASH 247 248### Format 249 250``` 251 FT.ADDHASH {index} {docId} {score} [LANGUAGE language] [REPLACE] 252``` 253 254### Description 255 256Adds a document to the index from an existing HASH key in Redis. 257 258#### Example 259```sql 260FT.ADDHASH idx hash1 1.0 REPLACE 261``` 262 263### Parameters 264 265- **index**: The Fulltext index name. The index must be first created with FT.CREATE 266 267- **docId**: The document's id. This has to be an existing HASH key in Redis that will hold the fields 268 the index needs. 269 270- **score**: The document's rank based on the user's ranking. This must be between 0.0 and 1.0. 271 If you don't have a score just set it to 1 272 273- **REPLACE**: If set, we will do an UPSERT style insertion - and delete an older version of the document if it exists. 274 275- **LANGUAGE language**: If set, we use a stemmer for the supplied language during indexing. Defaults 276 to English. 277 If an unsupported language is sent, the command returns an error. 278 The supported languages are: 279 280 > "arabic", "danish", "dutch", "english", "finnish", "french", 281 > "german", "hungarian", "italian", "norwegian", "portuguese", "romanian", 282 > "russian", "spanish", "swedish", "tamil", "turkish" 283 284### Complexity 285 286O(n), where n is the number of tokens in the document 287 288### Returns 289 290OK on success, or an error if something went wrong. 291 292--- 293 294## FT.ALTER SCHEMA ADD 295 296### Format 297 298``` 299FT.ALTER {index} SCHEMA ADD {field} {options} ... 300``` 301 302### Description 303 304Adds a new field to the index. 305 306Adding a field to the index will cause any future document updates to use the new field when 307indexing. Existing documents will not be reindexed. 308 309!!! note 310 Depending on how the index was created, you may be limited by the amount of additional text 311 fields which can be added to an existing index. If the current index contains less than 32 312 text fields, then `SCHEMA ADD` will only be able to add up to 32 fields (meaning that the 313 index will only ever be able to contain 32 total text fields). If you wish for the index to 314 contain more than 32 fields, create it with the `MAXTEXTFIELDS` option. 315 316#### Example 317```sql 318FT.ALTER idx SCHEMA ADD id2 NUMERIC SORTABLE 319``` 320 321### Parameters 322 323* **index**: the index name. 324* **field**: the field name. 325* **options**: the field options - refer to `FT.CREATE` for more information. 326 327### Complexity 328 329O(1) 330 331### Returns 332 333OK or an error. 334 335 336--- 337 338## FT.ALIASADD 339## FT.ALIASUPDATE 340## FT.ALIASDEL 341 342### Format 343 344``` 345FT.ALIASADD {name} {index} 346FT.ALIASUPDATE {name} {index} 347FT.ALIASDEL {name} 348``` 349 350The `FT.ALIASADD` and `FT.ALIASDEL` commands will add or remove an alias from 351an index. Index aliases can be used to refer to actual indexes in data 352commands such as `FT.SEARCH` or `FT.ADD`. This allows an administrator 353to transparently redirect application queries to alternative indexes. 354 355Indexes can have more than one alias, though an alias cannot refer to another 356alias. 357 358The `FT.ALIASUPDATE` command differs from the `FT.ALIASADD` command in that 359it will remove the alias association with a previous index, if any. `FT.ALIASDD` 360will fail, on the other hand, if the alias is already associated with another 361index. 362 363### Complexity 364 365O(1) 366 367### Returns 368 369OK or an error. 370 371--- 372 373## FT.INFO 374 375### Format 376 377``` 378FT.INFO {index} 379``` 380 381### Description 382 383Returns information and statistics on the index. Returned values include: 384 385* Number of documents. 386* Number of distinct terms. 387* Average bytes per record. 388* Size and capacity of the index buffers. 389 390#### Example 391```bash 392127.0.0.1:6379> ft.info wik{0} 393 1) index_name 394 2) wikipedia 395 3) fields 396 4) 1) 1) title 397 2) type 398 3) FULLTEXT 399 4) weight 400 5) "1" 401 2) 1) body 402 2) type 403 3) FULLTEXT 404 4) weight 405 5) "1" 406 5) num_docs 407 6) "502694" 408 7) num_terms 409 8) "439158" 410 9) num_records 41110) "8098583" 41211) inverted_sz_mb 41312) "45.58 41413) inverted_cap_mb 41514) "56.61 41615) inverted_cap_ovh 41716) "0.19 41817) offset_vectors_sz_mb 41918) "9.27 42019) skip_index_size_mb 42120) "7.35 42221) score_index_size_mb 42322) "30.8 42423) records_per_doc_avg 42524) "16.1 42625) bytes_per_record_avg 42726) "5.90 42827) offsets_per_term_avg 42928) "1.20 43029) offset_bits_per_record_avg 43130) "8.00 432``` 433 434### Parameters 435 436- **index**: The Fulltext index name. The index must be first created with FT.CREATE 437 438### Complexity 439 440O(1) 441 442### Returns 443 444Array Response. A nested array of keys and values. 445 446--- 447 448## FT.SEARCH 449 450### Format 451 452``` 453FT.SEARCH {index} {query} [NOCONTENT] [VERBATIM] [NOSTOPWORDS] [WITHSCORES] [WITHPAYLOADS] [WITHSORTKEYS] 454 [FILTER {numeric_field} {min} {max}] ... 455 [GEOFILTER {geo_field} {lon} {lat} {radius} m|km|mi|ft] 456 [INKEYS {num} {key} ... ] 457 [INFIELDS {num} {field} ... ] 458 [RETURN {num} {field} ... ] 459 [SUMMARIZE [FIELDS {num} {field} ... ] [FRAGS {num}] [LEN {fragsize}] [SEPARATOR {separator}]] 460 [HIGHLIGHT [FIELDS {num} {field} ... ] [TAGS {open} {close}]] 461 [SLOP {slop}] [INORDER] 462 [LANGUAGE {language}] 463 [EXPANDER {expander}] 464 [SCORER {scorer}] [EXPLAINSCORE] 465 [PAYLOAD {payload}] 466 [SORTBY {field} [ASC|DESC]] 467 [LIMIT offset num] 468``` 469 470### Description 471 472Searches the index with a textual query, returning either documents or just ids. 473 474### Example 475```sql 476FT.SEARCH idx "@text:morphix=>{$phonetic:false}" 477``` 478 479### Parameters 480 481- **index**: The index name. The index must be first created with `FT.CREATE`. 482- **query**: the text query to search. If it's more than a single word, put it in quotes. 483 Refer to [query syntax](Query_Syntax.md) for more details. 484 485- **NOCONTENT**: If it appears after the query, we only return the document ids and not 486 the content. This is useful if RediSearch is only an index on an external document collection 487- **VERBATIM**: if set, we do not try to use stemming for query expansion but search the query terms 488 verbatim. 489- **NOSTOPWORDS**: If set, we do not filter stopwords from the query. 490- **WITHSCORES**: If set, we also return the relative internal score of each document. this can be 491 used to merge results from multiple instances 492- **WITHPAYLOADS**: If set, we retrieve optional document payloads (see FT.ADD). 493 the payloads follow the document id, and if `WITHSCORES` was set, follow the scores. 494- **WITHSORTKEYS**: Only relevant in conjunction with **SORTBY**. Returns the value of the sorting key, 495 right after the id and score and /or payload if requested. This is usually not needed by users, and 496 exists for distributed search coordination purposes. 497 498- **FILTER numeric_field min max**: If set, and numeric_field is defined as a numeric field in 499 FT.CREATE, we will limit results to those having numeric values ranging between min and max. 500 min and max follow ZRANGE syntax, and can be **-inf**, **+inf** and use `(` for exclusive ranges. 501 Multiple numeric filters for different fields are supported in one query. 502- **GEOFILTER {geo_field} {lon} {lat} {radius} m|km|mi|ft**: If set, we filter the results to a given radius 503 from lon and lat. Radius is given as a number and units. See [GEORADIUS](https://redis.io/commands/georadius) 504 for more details. 505- **INKEYS {num} {field} ...**: If set, we limit the result to a given set of keys specified in the 506 list. 507 the first argument must be the length of the list, and greater than zero. 508 Non-existent keys are ignored - unless all the keys are non-existent. 509- **INFIELDS {num} {field} ...**: If set, filter the results to ones appearing only in specific 510 fields of the document, like title or URL. num is the number of specified field arguments 511 512- **RETURN {num} {field} ...**: Use this keyword to limit which fields from the document are returned. 513 `num` is the number of fields following the keyword. If `num` is 0, it acts like `NOCONTENT`. 514- **SUMMARIZE ...**: Use this option to return only the sections of the field which contain the 515 matched text. 516 See [Highlighting](Highlight.md) for more details 517- **HIGHLIGHT ...**: Use this option to format occurrences of matched text. See [Highligting](Highlight.md) for more 518 details 519- **SLOP {slop}**: If set, we allow a maximum of N intervening number of unmatched offsets between 520 phrase terms. (i.e the slop for exact phrases is 0) 521- **INORDER**: If set, and usually used in conjunction with SLOP, we make sure the query terms appear 522 in the same order in the document as in the query, regardless of the offsets between them. 523- **LANGUAGE {language}**: If set, we use a stemmer for the supplied language during search for query 524 expansion. 525 If querying documents in Chinese, this should be set to `chinese` in order to 526 properly tokenize the query terms. 527 Defaults to English. If an unsupported language is sent, the command returns an error. 528 See FT.ADD for the list of languages. 529 530- **EXPANDER {expander}**: If set, we will use a custom query expander instead of the stemmer. [See Extensions](Extensions.md). 531- **SCORER {scorer}**: If set, we will use a custom scoring function defined by the user. [See Extensions](Extensions.md). 532- **EXPLAINSCORE**: If set, will return a textual description of how the scores were calculated. 533- **PAYLOAD {payload}**: Add an arbitrary, binary safe payload that will be exposed to custom scoring 534 functions. [See Extensions](Extensions.md). 535 536- **SORTBY {field} [ASC|DESC]**: If specified, the results 537 are ordered by the value of this field. This applies to both text and numeric fields. 538- **LIMIT first num**: If the parameters appear after the query, we limit the results to 539 the offset and number of results given. The default is 0 10. 540 Note that you can use `LIMIT 0 0` to count the number of documents in 541 the resultset without actually returning them. 542 543### Complexity 544 545O(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. 546 547The 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. 548 549### Returns 550 551**Array reply,** where the first element is the total number of results, and then pairs of document id, and a nested array of field/value. 552 553If **NOCONTENT** was given, we return an array where the first element is the total number of results, and the rest of the members are document ids. 554 555--- 556 557## FT.AGGREGATE 558 559### Format 560 561``` 562FT.AGGREGATE {index_name} 563 {query_string} 564 [VERBATIM] 565 [LOAD {nargs} {property} ...] 566 [GROUPBY {nargs} {property} ... 567 REDUCE {func} {nargs} {arg} ... [AS {name:string}] 568 ... 569 ] ... 570 [SORTBY {nargs} {property} [ASC|DESC] ... [MAX {num}]] 571 [APPLY {expr} AS {alias}] ... 572 [LIMIT {offset} {num}] ... 573 [FILTER {expr}] ... 574``` 575 576### Description 577 578Runs a search query on an index, and performs aggregate transformations on the results, extracting statistics etc from them. See [the full documentation on aggregations](Aggregations.md) for further details. 579 580### Example 581```sql 582FT.AGGREGATE idx "@url:\"about.html\"" 583 APPLY "@timestamp - (@timestamp % 86400)" AS day 584 GROUPBY 2 @day @country 585 REDUCE count 0 AS num_visits 586 SORTBY 4 @day ASC @country DESC 587``` 588 589### Parameters 590 591* **index_name**: The index the query is executed against. 592 593* **query_string**: The base filtering query that retrieves the documents. It follows 594 **the exact same syntax** as the search query, including filters, unions, not, optional, etc. 595 596* **LOAD {nargs} {property} …**: Load document fields from the document HASH objects. This should be 597 avoided as a general rule of thumb. Fields needed for aggregations should be stored as **SORTABLE**, 598 where they are available to the aggregation pipeline with very low latency. LOAD hurts the 599 performance of aggregate queries considerably, since every processed record needs to execute the 600 equivalent of HMGET against a Redis key, which when executed over millions of keys, amounts to very 601 high processing times. 602 603* **GROUPBY {nargs} {property}**: Group the results in the pipeline based on one or more properties. 604 Each group should have at least one reducer (See below), a function that handles the group entries, 605 either counting them, or performing multiple aggregate operations (see below). 606 * **REDUCE {func} {nargs} {arg} … [AS {name}]**: Reduce the matching results in each group into a single record, using a reduction function. For example COUNT will count the number of records in the group. See the Reducers section below for more details on available reducers. 607 608 The reducers can have their own property names using the `AS {name}` optional argument. If a name is not given, the resulting name will be the name of the reduce function and the group properties. For example, if a name is not given to COUNT_DISTINCT by property `@foo`, the resulting name will be `count_distinct(@foo)`. 609 610* **SORTBY {nargs} {property} {ASC|DESC} [MAX {num}]**: Sort the pipeline up until the point of SORTBY, 611 using a list of properties. By default, sorting is ascending, but `ASC` or `DESC ` can be added for 612 each property. `nargs` is the number of sorting parameters, including ASC and DESC. for example: 613 `SORTBY 4 @foo ASC @bar DESC`. 614 615 `MAX` is used to optimized sorting, by sorting only for the n-largest elements. Although it is not connected to `LIMIT`, you usually need just `SORTBY … MAX` for common queries. 616 617* **APPLY {expr} AS {name}**: Apply a 1-to-1 transformation on one or more properties, and either 618 store the result as a new property down the pipeline, or replace any property using this 619 transformation. `expr` is an expression that can be used to perform arithmetic operations on numeric 620 properties, or functions that can be applied on properties depending on their types (see below), or 621 any combination thereof. For example: `APPLY "sqrt(@foo)/log(@bar) + 5" AS baz` will evaluate this 622 expression dynamically for each record in the pipeline and store the result as a new property called 623 baz, that can be referenced by further APPLY / SORTBY / GROUPBY / REDUCE operations down the 624 pipeline. 625 626* **LIMIT {offset} {num}**. Limit the number of results to return just `num` results starting at index 627 `offset` (zero-based). AS mentioned above, it is much more efficient to use `SORTBY … MAX` if you 628 are interested in just limiting the output of a sort operation. 629 630 However, limit can be used to limit results without sorting, or for paging the n-largest results as determined by `SORTBY MAX`. For example, getting results 50-100 of the top 100 results is most efficiently expressed as `SORTBY 1 @foo MAX 100 LIMIT 50 50`. Removing the MAX from SORTBY will result in the pipeline sorting _all_ the records and then paging over results 50-100. 631 632* **FILTER {expr}**. Filter the results using predicate expressions relating to values in each result. 633 They are is applied post-query and relate to the current state of the pipeline. 634 635### Complexity 636 637Non-deterministic. Depends on the query and aggregations performed, but it is usually linear to the number of results returned. 638 639### Returns 640 641Array Response. Each row is an array and represents a single aggregate result. 642 643### Example output 644 645Here we are counting GitHub events by user (actor), to produce the most active users: 646 647```sh 648127.0.0.1:6379> FT.AGGREGATE gh "*" GROUPBY 1 @actor REDUCE COUNT 0 AS num SORTBY 2 @num DESC MAX 10 649 1) (integer) 284784 650 2) 1) "actor" 651 2) "lombiqbot" 652 3) "num" 653 4) "22197" 654 3) 1) "actor" 655 2) "codepipeline-test" 656 3) "num" 657 4) "17746" 658 4) 1) "actor" 659 2) "direwolf-github" 660 3) "num" 661 4) "10683" 662 5) 1) "actor" 663 2) "ogate" 664 3) "num" 665 4) "6449" 666 6) 1) "actor" 667 2) "openlocalizationtest" 668 3) "num" 669 4) "4759" 670 7) 1) "actor" 671 2) "digimatic" 672 3) "num" 673 4) "3809" 674 8) 1) "actor" 675 2) "gugod" 676 3) "num" 677 4) "3512" 678 9) 1) "actor" 679 2) "xdzou" 680 3) "num" 681 4) "3216" 68210) 1) "actor" 683 2) "opstest" 684 3) "num" 685 4) "2863" 68611) 1) "actor" 687 2) "jikker" 688 3) "num" 689 4) "2794" 690(0.59s) 691``` 692 693--- 694 695## FT.EXPLAIN 696 697### Format 698 699``` 700FT.EXPLAIN {index} {query} 701``` 702 703### Description 704 705Returns the execution plan for a complex query. 706 707In the returned response, a `+` on a term is an indication of stemming. 708 709### Example 710```sh 711$ redis-cli --raw 712 713127.0.0.1:6379> FT.EXPLAIN rd "(foo bar)|(hello world) @date:[100 200]|@date:[500 +inf]" 714INTERSECT { 715 UNION { 716 INTERSECT { 717 foo 718 bar 719 } 720 INTERSECT { 721 hello 722 world 723 } 724 } 725 UNION { 726 NUMERIC {100.000000 <= x <= 200.000000} 727 NUMERIC {500.000000 <= x <= inf} 728 } 729} 730``` 731 732### Parameters 733 734- **index**: The index name. The index must be first created with FT.CREATE 735- **query**: The query string, as if sent to FT.SEARCH 736 737### Complexity 738 739O(1) 740 741### Returns 742 743String Response. A string representing the execution plan (see above example). 744 745**Note**: You should use `redis-cli --raw` to properly read line-breaks in the returned response. 746 747--- 748 749## FT.EXPLAINCLI 750 751### Format 752 753``` 754FT.EXPLAINCLI {index} {query} 755``` 756 757### Description 758 759Returns the execution plan for a complex query but formatted for easier reading without using `redis-cli --raw`. 760 761In the returned response, a `+` on a term is an indication of stemming. 762 763### Example 764```sh 765$ redis-cli 766 767127.0.0.1:6379> FT.EXPLAINCLI rd "(foo bar)|(hello world) @date:[100 200]|@date:[500 +inf]" 768 1) INTERSECT { 769 2) UNION { 770 3) INTERSECT { 771 4) UNION { 772 5) foo 773 6) +foo(expanded) 774 7) } 775 8) UNION { 776 9) bar 77710) +bar(expanded) 77811) } 77912) } 78013) INTERSECT { 78114) UNION { 78215) hello 78316) +hello(expanded) 78417) } 78518) UNION { 78619) world 78720) +world(expanded) 78821) } 78922) } 79023) } 79124) UNION { 79225) NUMERIC {100.000000 <= @date <= 200.000000} 79326) NUMERIC {500.000000 <= @date <= inf} 79427) } 79528) } 79629) 797``` 798 799### Parameters 800 801- **index**: The index name. The index must be first created with FT.CREATE 802- **query**: The query string, as if sent to FT.SEARCH 803 804### Complexity 805 806O(1) 807 808### Returns 809 810String Response. A string representing the execution plan (see above example). 811 812--- 813 814## FT.DEL 815 816### Format 817 818``` 819FT.DEL {index} {doc_id} [DD] 820``` 821 822### Description 823 824Deletes a document from the index. Returns 1 if the document was in the index, or 0 if not. 825 826After deletion, the document can be re-added to the index. It will get a different internal id and will be a new document from the index's POV. 827 828!!! warning "FT.DEL does not delete the actual document By default!" 829 830 Since RediSearch regards documents as separate entities to the index and allows things like adding existing documents or indexing without saving the document - by default FT.DEL only deletes the reference to the document from the index, not the actual Redis HASH key where the document is stored. 831 832 Specifying **DD** (Delete Document) after the document ID, will make RediSearch also delete the actual document **if it is in the index**. 833 834 Alternatively, you can just send an extra **DEL {doc_id}** to redis and delete the document directly. You can run both of them in a MULTI transaction. 835 836### Example 837```sql 838FT.DEL idx doc1 839``` 840 841### Parameters 842 843- **index**: The index name. The index must be first created with FT.CREATE 844- **doc_id**: the id of the document to be deleted. It does not actually delete the HASH key in which 845 the document is stored. Use DEL to do that manually if needed. 846 847 848### Complexity 849 850O(1) 851 852### Returns 853 854Integer Reply: 1 if the document was deleted, 0 if not. 855 856--- 857 858## FT.GET 859 860### Format 861 862``` 863FT.GET {index} {doc id} 864``` 865 866### Description 867 868Returns the full contents of a document. 869 870Currently it is equivalent to HGETALL, but this is future-proof and will allow us to change the internal representation of documents inside Redis in the future. In addition, it allows simpler implementation of fetching documents in clustered mode. 871 872If the document does not exist or is not a HASH object, we return a NULL reply 873 874### Example 875```sql 876FT.GET idx doc1 877``` 878 879### Parameters 880 881- **index**: The index name. The index must be first created with FT.CREATE 882- **documentId**: The id of the document as inserted to the index 883 884### Returns 885 886Array Reply: Key-value pairs of field names and values of the document 887 888--- 889 890## FT.MGET 891 892### Format 893 894``` 895FT.MGET {index} {docId} ... 896``` 897 898### Description 899 900Returns the full contents of multiple documents. 901 902Currently it is equivalent to calling multiple HGETALL commands, although faster. 903This command is also future-proof and will allow us to change the internal representation of documents inside Redis in the future. 904In addition, it allows simpler implementation of fetching documents in clustered mode. 905 906We return an array with exactly the same number of elements as the number of keys sent to the command. 907 908Each element, in turn, is an array of key-value pairs representing the document. 909 910If a document is not found or is not a valid HASH object, its place in the parent array is filled with a Null reply object. 911 912### Example 913```sql 914FT.MGET idx doc1 doc2 915``` 916 917### Parameters 918 919- **index**: The Fulltext index name. The index must be first created with FT.CREATE 920- **documentIds**: The ids of the requested documents as inserted to the index 921 922### Returns 923 924Array Reply: An array with exactly the same number of elements as the number of keys sent to the command. Each element in it is either an array representing the document or Null if it was not found. 925 926--- 927 928## FT.DROP 929 930### Format 931 932``` 933FT.DROP {index} [KEEPDOCS] 934``` 935 936### Description 937 938Deletes all the keys associated with the index. 939 940By default, DROP deletes the document hashes as well, but adding the KEEPDOCS option keeps the documents in place, ready for re-indexing. 941 942If no other data is on the Redis instance, this is equivalent to FLUSHDB, apart from the fact 943that the index specification is not deleted. 944 945### Example 946```sql 947FT.DROP idx KEEPDOCS 948``` 949 950### Parameters 951 952- **index**: The Fulltext index name. The index must be first created with FT.CREATE 953- **KEEPDOCS**: If set, the drop operation will not delete the actual document hashes. 954 955### Returns 956 957Status Reply: OK on success. 958 959--- 960 961## FT.TAGVALS 962 963### Format 964 965``` 966FT.TAGVALS {index} {field_name} 967``` 968 969### Description 970 971Returns the distinct tags indexed in a [Tag field](Tags.md). 972 973This is useful if your tag field indexes things like cities, categories, etc. 974 975!!! warning "Limitations" 976 977 There is no paging or sorting, the tags are not alphabetically sorted. 978 979 This command only operates on [Tag fields](Tags.md). 980 981 The strings return lower-cased and stripped of whitespaces, but otherwise unchanged. 982 983### Example 984```sql 985FT.TAGVALS idx myTag 986``` 987 988### Parameters 989 990- **index**: The Fulltext index name. The index must be first created with FT.CREATE 991- **filed_name**: The name of a Tag file defined in the schema. 992 993### Returns 994 995Array Reply: All the distinct tags in the tag index. 996 997### Complexity 998 999O(n), n being the cardinality of the tag field. 1000 1001--- 1002 1003## FT.SUGADD 1004 1005### Format 1006 1007``` 1008FT.SUGADD {key} {string} {score} [INCR] [PAYLOAD {payload}] 1009``` 1010 1011### Description 1012 1013Adds a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the 1014index definitions, and leaves creating and updating suggestions dictionaries to the user. 1015 1016### Example 1017```sql 1018FT.SUGADD ac "hello world" 1 1019``` 1020 1021### Parameters 1022 1023- **key**: the suggestion dictionary key. 1024- **string**: the suggestion string we index 1025- **score**: a floating point number of the suggestion string's weight 1026- **INCR**: if set, we increment the existing entry of the suggestion by the given score, instead of 1027 replacing the score. This is useful for updating the dictionary based on user queries in real time 1028- **PAYLOAD {payload}**: If set, we save an extra payload with the suggestion, that can be fetched by 1029 adding the `WITHPAYLOADS` argument to `FT.SUGGET`. 1030 1031### Returns 1032 1033Integer Reply: the current size of the suggestion dictionary. 1034 1035--- 1036 1037## FT.SUGGET 1038 1039### Format 1040 1041``` 1042FT.SUGGET {key} {prefix} [FUZZY] [WITHSCORES] [WITHPAYLOADS] [MAX num] 1043``` 1044 1045### Description 1046 1047Gets completion suggestions for a prefix. 1048 1049### Example 1050```sql 1051FT.SUGGET ac hell FUZZY MAX 3 WITHSCORES 1052``` 1053 1054### Parameters 1055 1056- **key**: the suggestion dictionary key. 1057- **prefix**: the prefix to complete on 1058- **FUZZY**: if set, we do a fuzzy prefix search, including prefixes at Levenshtein distance of 1 from 1059 the prefix sent 1060- **MAX num**: If set, we limit the results to a maximum of `num` (default: 5). 1061- **WITHSCORES**: If set, we also return the score of each suggestion. this can be used to merge 1062 results from multiple instances 1063- **WITHPAYLOADS**: If set, we return optional payloads saved along with the suggestions. If no 1064 payload is present for an entry, we return a Null Reply. 1065 1066### Returns 1067 1068Array Reply: a list of the top suggestions matching the prefix, optionally with score after each entry 1069 1070--- 1071 1072## FT.SUGDEL 1073 1074### Format 1075 1076``` 1077FT.SUGDEL {key} {string} 1078``` 1079 1080### Description 1081 1082Deletes a string from a suggestion index. 1083 1084### Example 1085```sql 1086FT.SUGDEL ac "hello world" 1087``` 1088 1089### Parameters 1090 1091- **key**: the suggestion dictionary key. 1092- **string**: the string to delete 1093 1094### Returns 1095 1096Integer Reply: 1 if the string was found and deleted, 0 otherwise. 1097 1098--- 1099 1100## FT.SUGLEN 1101 1102### Format 1103 1104``` 1105FT.SUGLEN {key} 1106``` 1107 1108### Description 1109 1110Gets the size of an auto-complete suggestion dictionary 1111 1112### Example 1113```sql 1114FT.SUGDEL ac 1115``` 1116 1117### Parameters 1118 1119* **key**: the suggestion dictionary key. 1120 1121### Returns 1122 1123Integer Reply: the current size of the suggestion dictionary. 1124 1125--- 1126 1127## FT.OPTIMIZE 1128 1129!!! warning "This command is deprecated" 1130 Index optimizations are done by the internal garbage collector in the background. Client libraries should not implement this command and remove it if they haven't already. 1131 1132### Format 1133 1134``` 1135FT.OPTIMIZE {index} 1136``` 1137 1138### Description 1139 1140This command is deprecated. 1141 1142--- 1143 1144## FT.SYNADD 1145 1146### Format 1147 1148``` 1149FT.SYNADD <index name> <term1> <term2> ... 1150``` 1151 1152### Description 1153 1154Adds a synonym group. 1155 1156The command is used to create a new synonyms group. The command returns the synonym group id which can later be used to add additional terms to that synonym group. Only documents which were indexed after the adding operation will be affected. 1157 1158--- 1159 1160## FT.SYNUPDATE 1161 1162### Format 1163 1164``` 1165FT.SYNUPDATE <index name> <synonym group id> <term1> <term2> ... 1166``` 1167 1168### Description 1169 1170Updates a synonym group. 1171 1172The command is used to update an existing synonym group with additional terms. Only documents which were indexed after the update will be affected. 1173 1174--- 1175 1176## FT.SYNDUMP 1177 1178### Format 1179 1180``` 1181FT.SYNDUMP <index name> 1182``` 1183 1184### Description 1185 1186Dumps the contents of a synonym group. 1187 1188The command is used to dump the synonyms data structure. Returns a list of synonym terms and their synonym group ids. 1189 1190--- 1191 1192## FT.SPELLCHECK 1193 1194### Format 1195``` 1196 FT.SPELLCHECK {index} {query} 1197 [DISTANCE dist] 1198 [TERMS {INCLUDE | EXCLUDE} {dict} [TERMS ...]] 1199``` 1200 1201### Description 1202 1203Performs spelling correction on a query, returning suggestions for misspelled terms. 1204 1205See [Query Spelling Correction](Spellcheck.md) for more details. 1206 1207### Parameters 1208 1209* **index**: the index with the indexed terms. 1210 1211* **query**: the search query. 1212 1213* **TERMS**: specifies an inclusion (`INCLUDE`) or exclusion (`EXCLUDE`) custom dictionary named `{dict}`. Refer to [`FT.DICTADD`](Commands.md#ftdictadd), [`FT.DICTDEL`](Commands.md#ftdictdel) and [`FT.DICTDUMP`](Commands.md#ftdictdump) for managing custom dictionaries. 1214 1215* **DISTANCE**: the maximal Levenshtein distance for spelling suggestions (default: 1, max: 4). 1216 1217### Returns 1218 1219An array, in which each element represents a misspelled term from the query. The misspelled terms are ordered by their order of appearance in the query. 1220 1221Each misspelled term, in turn, is a 3-element array consisting of the constant string "TERM", the term itself and an array of suggestions for spelling corrections. 1222 1223Each element in the spelling corrections array consists of the score of the suggestion and the suggestion itself. The suggestions array, per misspelled term, is ordered in descending order by score. 1224 1225### Example output 1226 1227``` 12281) 1) "TERM" 1229 2) "{term1}" 1230 3) 1) 1) "{score1}" 1231 2) "{suggestion1}" 1232 2) 1) "{score2}" 1233 2) "{suggestion2}" 1234 . 1235 . 1236 . 12372) 1) "TERM" 1238 2) "{term2}" 1239 3) 1) 1) "{score1}" 1240 2) "{suggestion1}" 1241 2) 1) "{score2}" 1242 2) "{suggestion2}" 1243 . 1244 . 1245 . 1246. 1247. 1248. 1249 1250``` 1251 1252--- 1253 1254 1255## FT.DICTADD 1256 1257### Format 1258``` 1259 FT.DICTADD {dict} {term} [{term} ...] 1260``` 1261 1262### Description 1263 1264Adds terms to a dictionary. 1265 1266### Parameters 1267 1268* **dict**: the dictionary name. 1269 1270* **term**: the term to add to the dictionary. 1271 1272### Returns 1273 1274Returns int, specifically the number of new terms that were added. 1275 1276--- 1277 1278## FT.DICTDEL 1279 1280### Format 1281``` 1282 FT.DICTDEL {dict} {term} [{term} ...] 1283``` 1284 1285### Description 1286 1287Deletes terms from a dictionary. 1288 1289### Parameters 1290 1291* **dict**: the dictionary name. 1292 1293* **term**: the term to delete from the dictionary. 1294 1295### Returns 1296 1297Returns int, specifically the number of terms that were deleted. 1298 1299--- 1300 1301## FT.DICTDUMP 1302 1303### Format 1304``` 1305 FT.DICTDUMP {dict} 1306``` 1307 1308### Description 1309 1310Dumps all terms in the given dictionary. 1311 1312### Parameters 1313 1314* **dict**: the dictionary name. 1315 1316### Returns 1317 1318Returns an array, where each element is term (string). 1319 1320--- 1321 1322## FT.CONFIG 1323 1324### Format 1325``` 1326 FT.CONFIG <GET|HELP> {option} 1327 FT.CONFIG SET {option} {value} 1328``` 1329 1330### Description 1331 1332Retrieves, describes and sets runtime configuration options. 1333 1334### Parameters 1335 1336* **option**: the name of the configuration option, or '*' for all. 1337* **value**: a value for the configuration option. 1338 1339For details about the configuration options refer to [Configuring](Configuring.md). 1340 1341Setting values in runtime is supported for these configuration options: 1342 1343* `NOGC` 1344* `MINPREFIX` 1345* `MAXEXPANSIONS` 1346* `TIMEOUT` 1347* `ON_TIMEOUT` 1348* `MIN_PHONETIC_TERM_LEN` 1349 1350### Returns 1351 1352When provided with a valid option name, the `GET` subcommand returns a string with the current option's value. An array containing an array for each configuration option, consisting of the option's name and current value, is returned when '*' is provided. 1353 1354The `SET` subcommand returns 'OK' for valid runtime-settable option names and values. 1355