{
  "schema_version": 2,
  "id": "develop/ai/search-and-query/query/exact-match",
  "title": "Exact match queries",
  "url": "https://redis.io/docs/latest/develop/ai/search-and-query/query/exact-match/",
  "summary": "Perform simple exact match queries",
  "aliases": [
    "/develop/interact/search-and-query/query/exact-match"
  ],
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-11T15:33:04+01:00",
  "page_type": "content",
  "content_hash": "5d9201a30b146b8ea5defbe053f579b522cde7ed72564a684bed9e309fd12dd2",
  "sections": [
    {
      "id": "numeric-field",
      "title": "Numeric field",
      "role": "content",
      "text": "To perform an exact match query on a numeric field, you need to construct a range query with the same start and end value:\n\n[code example]\n\nAs described in the [article about range queries](https://redis.io/docs/latest/develop/ai/search-and-query/query/range), you can also use the `FILTER` argument:\n\n[code example]\n\nThe following examples show you how to query for bicycles with a price of exactly 270 USD:\n\nFoundational: Query numeric fields for exact matches using range syntax or equality operators when you need to find documents with specific numeric values\n\n**Difficulty:** Beginner\n\n**Commands:** FT.SEARCH\n\n**Complexity:**\n- FT.SEARCH: O(N)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    },
    {
      "id": "tag-field",
      "title": "Tag field",
      "role": "content",
      "text": "A tag is a short sequence of text, for example, \"new\" or \"Los Angeles\". \n\n> [!NOTE] Important\n> If you need to query for short texts, use a tag query instead of a full-text query. Tag fields are more space-efficient for storing index entries and often lead to lower query complexity for exact match queries.\n\nYou can construct a tag query for a single tag in the following way:\n\n[code example]\n\n> [!NOTE]\n> The curly brackets are mandatory for tag queries.\n\nThis short example shows you how to query for new bicycles:\n\nFoundational: Query tag fields for exact matches using curly bracket syntax when you need to find documents with specific categorical values\n\n**Difficulty:** Beginner\n\n**Commands:** FT.SEARCH\n\n**Complexity:**\n- FT.SEARCH: O(N)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]\n\n\n\nUse double quotes and [DIALECT 2](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/dialects#dialect-2) for exact match queries involving tags that contain special characters. As of v2.10, the only character that needs escaping in queries involving double-quoted tags is the double-quote character. Here's an example of using double-quoted tags that contain special characters:\n\nTag fields: Query tag fields with special characters using double-quoted syntax and DIALECT 2 when you need to match tags containing symbols or spaces\n\n**Difficulty:** Advanced\n\n**Commands:** FT.CREATE, JSON.SET, FT.SEARCH\n\n**Complexity:**\n- FT.CREATE: O(K)\n- JSON.SET: O(M+N)\n- FT.SEARCH: O(N)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    },
    {
      "id": "full-text-field",
      "title": "Full-text field",
      "role": "content",
      "text": "A detailed explanation of full-text queries is available in the [full-text queries documentation](https://redis.io/docs/latest/develop/ai/search-and-query/query/full-text). You can also query for an exact match of a phrase within a text field:\n\n[code example]\n\n> [!NOTE] Important\n> The phrase must be wrapped by escaped double quotes for an exact match query.\n>\n> You can't use a phrase that starts with a [stop word](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/stopwords).\n\nHere is an example for finding all bicycles that have a description containing the exact text 'rough terrain':\n\nText fields: Query text fields for exact phrase matches using escaped double quotes when you need to find documents containing specific multi-word phrases\n\n**Difficulty:** Intermediate\n\n**Commands:** FT.SEARCH\n\n**Complexity:**\n- FT.SEARCH: O(N)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), Python\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### Python\n\n[code example]"
    }
  ],
  "examples": [
    {
      "id": "numeric-field-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@field:[value value]\"\n\nor\n\nFT.SEARCH index \"@field:[value]\" DIALECT 2 # requires v2.10\n\nor\n\nFT.SEARCH index \"@field==value\" DIALECT 2 # requires v2.10",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex1",
      "language": "plaintext",
      "code": "FT.SEARCH index \"*\" FILTER field start end",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex2",
      "language": "plaintext",
      "code": "> FT.SEARCH idx:bicycle \"@price:[270 270]\"\n1) (integer) 1\n2) \"bicycle:0\"\n3) 1) \"$\"\n   2) \"{\\\"pickup_zone\\\":\\\"POLYGON((-74.0610 40.7578, ...\n\n> FT.SEARCH idx:bicycle \"@price:[270]\" # requires v2.10\n1) (integer) 1\n2) \"bicycle:0\"\n3) 1) \"$\"\n   2) \"{\\\"pickup_zone\\\":\\\"POLYGON((-74.0610 40.7578, ...\n\n> FT.SEARCH idx:bicycle \"@price==270\" # requires v2.10\n1) (integer) 1\n2) \"bicycle:0\"\n3) 1) \"$\"\n   2) \"{\\\"pickup_zone\\\":\\\"POLYGON((-74.0610 40.7578, ...\n\n> FT.SEARCH idx:bicycle \"*\" FILTER price 270 270\n1) (integer) 1\n2) \"bicycle:0\"\n3) 1) \"$\"\n   2) \"{\\\"pickup_zone\\\":\\\"POLYGON((-74.0610 40.7578, ...",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex3",
      "language": "csharp",
      "code": "SearchResult res1 = db.FT().Search(\n            \"idx:bicycle\",\n            new(\"@price:[270 270]\")\n        );\n        Console.WriteLine(res1.TotalResults); //    >>> 1\n\n        SearchResult res2 = db.FT().Search(\n            \"idx:bicycle\",\n            new Query().AddFilter(\n                new Query.NumericFilter(\"price\", 270, 270)\n            )\n        );\n        Console.WriteLine(res2.TotalResults); //    >>> 1",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex4",
      "language": "go",
      "code": "res1, err := rdb.FTSearch(ctx,\n\t\t\"idx:bicycle\", \"@price:[270 270]\",\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res1.Total) // >>> 1\n\n\tfor _, doc := range res1.Docs {\n\t\tfmt.Println(doc.ID)\n\t}\n\t// >>> bicycle:0\n\n\tres2, err := rdb.FTSearchWithArgs(ctx,\n\t\t\"idx:bicycle\",\n\t\t\"*\",\n\t\t&redis.FTSearchOptions{\n\t\t\tFilters: []redis.FTSearchFilter{\n\t\t\t\t{\n\t\t\t\t\tFieldName: \"price\",\n\t\t\t\t\tMin:       270,\n\t\t\t\t\tMax:       270,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res2.Total) // >>> 1\n\n\tfor _, doc := range res2.Docs {\n\t\tfmt.Println(doc.ID)\n\t}\n\t// >>> bicycle:0",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex5",
      "language": "java",
      "code": "CompletableFuture<SearchReply<String, String>> priceResults = asyncCommands.ftSearch(\"idx:bicycle\", \"@price:[270]\")\n\n                    .thenApply(res -> {\n\n                        res.getResults().forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:0\n\n                        return res;\n                    }).toCompletableFuture();",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex6",
      "language": "java",
      "code": "Mono<SearchReply<String, String>> priceResults = reactiveCommands.ftSearch(\"idx:bicycle\", \"@price:[270]\")\n                    .doOnNext(res -> {\n                        res.getResults().forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:0\n                    });",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex7",
      "language": "java",
      "code": "SearchResult res1 = jedis.ftSearch(\"idx:bicycle\", \"@price:[270 270]\");\n        System.out.println(res1.getTotalResults()); // >>> 1\n\n        List<Document> docs1 = res1.getDocuments();\n\n        for (int i = 0; i < docs1.size(); i++) {\n            System.out.println(docs1.get(i).getId());\n        }\n        // >>> bicycle:0\n\n        SearchResult res2 = jedis.ftSearch(\"idx:bicycle\",\n            \"*\",\n            FTSearchParams.searchParams()\n                    .filter(\"price\", 270, 270)\n        );\n        System.out.println(res2.getTotalResults()); // >>> 1\n\n        List<Document> docs2 = res2.getDocuments();\n\n        for (int i = 0; i < docs2.size(); i++) {\n            System.out.println(docs2.get(i).getId());\n        }\n        // >>> bicycle:0",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex8",
      "language": "javascript",
      "code": "const res1 = await client.ft.search('idx:bicycle', '@price:[270 270]');\nconsole.log(res1.total); // >>> 1\n\ntry {\n    const res2 = await client.ft.search('idx:bicycle', '@price:[270]');\n    console.log(res2.total); // >>> 1\n    assert.strictEqual(res2.total, 1);\n} catch (err) {\n    console.log(\"'@price:[270]' syntax not yet supported.\");\n}\n\ntry {\n    const res3 = await client.ft.search('idx:bicycle', '@price==270');\n    console.log(res3.total); // >>> 1\n    assert.strictEqual(res3.total, 1);\n} catch (err) {\n    console.log(\"'@price==270' syntax not yet supported.\");\n}\n\n// FILTER is not supported\n// const res4 = await client.ft.search('idx:bicycle', '*', {\n//   FILTER: {\n//       field: 'price',\n//       min: 270,\n//       max: 270,\n//   }\n// });\n// console.log(res4.total); // >>> 1",
      "section_id": "numeric-field"
    },
    {
      "id": "numeric-field-ex9",
      "language": "python",
      "code": "res = index.search(Query(\"@price:[270 270]\"))\nprint(res.total)\n# >>> 1\n\ntry:\n    res = index.search(Query(\"@price:[270]\")) # not yet supported in redis-py\n    print(res.total)\n    # >>> 1\n    assert res.total == 1\nexcept Exception:\n    print(\"'@price:[270]' syntax not yet supported.\")\n\ntry:\n    res = index.search(Query(\"@price==270\")) # not yet supported in redis-py\n    print(res.total)\n    # >>> 1\n    assert res.total == 1\nexcept Exception:\n    print(\"'@price==270' syntax not yet supported.\")\n\nquery = Query(\"*\").add_filter(NumericFilter(\"price\", 270, 270))\nres = index.search(query)\nprint(res.total)\n# >>> 1",
      "section_id": "numeric-field"
    },
    {
      "id": "tag-field-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@field:{tag}\"",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex1",
      "language": "plaintext",
      "code": "> FT.SEARCH idx:bicycle \"@condition:{new}\"\n 1) (integer) 5\n 2) \"bicycle:0\"\n 3) 1) \"$\"\n    2) \"{\\\"pickup_zone\\\":\\\"POLYGON((-74.0610 40.7578, -73.9510 40.7578, -73.9510 40.6678, -74.0610 40.6678, -74.0610 40.7578))\\\",\\\"store_location\\\":\\\"-74.0060,40.7128\\\",\\\"brand\\\":\\\"Velorim\\\",\\\"model\\\":\\\"Jigger\\\",\\\"price\\\":270,\\\"description\\\":\\\"Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids\\xe2\\x80\\x99 pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.\\\",\\\"condition\\\":\\\"new\\\"}\"\n 4) \"bicycle:5\"\n... output truncated for AI-facing Markdown ...\n    2) \"{\\\"pickup_zone\\\":\\\"POLYGON((1.9450 41.4301, 2.4018 41.4301, 2.4018 41.1987, 1.9450 41.1987, 1.9450 41.4301))\\\",\\\"store_location\\\":\\\"2.1734, 41.3851\\\",\\\"brand\\\":\\\"nHill\\\",\\\"model\\\":\\\"Summit\\\",\\\"price\\\":1200,\\\"description\\\":\\\"This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\\xe2\\x80\\x99re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.\\\",\\\"condition\\\":\\\"new\\\"}\"",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex2",
      "language": "csharp",
      "code": "SearchResult res3 = db.FT().Search(\n            \"idx:bicycle\",\n            new(\"@condition:{new}\")\n        );\n        Console.WriteLine(res3.TotalResults);   // >>> 4",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex3",
      "language": "go",
      "code": "res3, err := rdb.FTSearch(ctx,\n\t\t\"idx:bicycle\", \"@condition:{new}\",\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res3.Total) // >>> 5\n\n\tdocs := res3.Docs\n\tslices.SortFunc(docs, func(a, b redis.Document) int {\n\t\treturn strings.Compare(a.ID, b.ID)\n\t})\n\n\tfor _, doc := range docs {\n\t\tfmt.Println(doc.ID)\n\t}\n\t// >>> bicycle:0\n\t// >>> bicycle:5\n\t// >>> bicycle:6\n\t// >>> bicycle:7\n\t// >>> bicycle:8",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex4",
      "language": "java",
      "code": "CompletableFuture<SearchReply<String, String>> conditionResults = asyncCommands\n                    .ftSearch(\"idx:bicycle\", \"@condition:{new}\").thenApply(res -> {\n                        res.getResults().stream().sorted((doc1, doc2) -> doc1.getId().compareTo(doc2.getId())).forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:0\n                        // >>> ID: bicycle:5\n                        // >>> ID: bicycle:6\n                        // >>> ID: bicycle:7\n                        // >>> ID: bicycle:8\n\n                        return res;\n                    }).toCompletableFuture();",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex5",
      "language": "java",
      "code": "Mono<SearchReply<String, String>> conditionResults = reactiveCommands.ftSearch(\"idx:bicycle\", \"@condition:{new}\")\n                    .doOnNext(res -> {\n                        res.getResults().stream().sorted((doc1, doc2) -> doc1.getId().compareTo(doc2.getId())).forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:0\n                        // >>> ID: bicycle:5\n                        // >>> ID: bicycle:6\n                        // >>> ID: bicycle:7\n                        // >>> ID: bicycle:8\n                    });",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex6",
      "language": "java",
      "code": "SearchResult res3 = jedis.ftSearch(\"idx:bicycle\", \"@condition:{new}\");\n        System.out.println(res3.getTotalResults()); // >>> 5\n\n        List<Document> docs3 = res3.getDocuments();\n\n        for (int i = 0; i < docs3.size(); i++) {\n            System.out.println(docs3.get(i).getId());\n        }\n        // >>> bicycle:5\n        // >>> bicycle:0\n        // >>> bicycle:6\n        // >>> bicycle:7\n        // >>> bicycle:8",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex7",
      "language": "javascript",
      "code": "const res5 = await client.ft.search('idx:bicycle', '@condition:{new}');\nconsole.log(res5.total); // >>> 5",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex8",
      "language": "python",
      "code": "res = index.search(Query(\"@condition:{new}\"))\nprint(res.total)\n# >>> 5",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex9",
      "language": "plaintext",
      "code": "> FT.CREATE idx:email ON JSON PREFIX 1 key: SCHEMA $.email AS email TAG\nOK\n> JSON.SET key:1 $ '{\"email\": \"test@redis.com\"}'\nOK\n> FT.SEARCH idx:email '@email:{\"test@redis.com\"}' DIALECT 2\n1) (integer) 1\n2) \"key:1\"\n3) 1) \"$\"\n   2) \"{\\\"email\\\":\\\"test@redis.com\\\"}\"",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex10",
      "language": "csharp",
      "code": "Schema emailSchema = new Schema()\n            .AddTagField(new FieldName(\"$.email\", \"email\"));\n\n        FTCreateParams emailParams = new FTCreateParams()\n            .AddPrefix(\"key:\")\n            .On(IndexDataType.JSON);\n\n        db.FT().Create(\"idx:email\", emailParams, emailSchema);\n\n        db.JSON().Set(\"key:1\", \"$\", \"{\\\"email\\\": \\\"test@redis.com\\\"}\");\n\n\n\n        SearchResult res4 = db.FT().Search(\n            \"idx:email\",\n            new Query(\"@email:{test\\\\@redis\\\\.com}\").Dialect(2)\n        );\n        Console.WriteLine(res4.TotalResults);   // >>> 1",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex11",
      "language": "go",
      "code": "res4, err := rdb.FTCreate(ctx,\n\t\t\"idx:email\",\n\t\t&redis.FTCreateOptions{\n\t\t\tOnJSON: true,\n\t\t\tPrefix: []interface{}{\"key:\"},\n\t\t},\n\t\t&redis.FieldSchema{\n\t\t\tFieldName: \"$.email\",\n\t\t\tAs:        \"email\",\n\t\t\tFieldType: redis.SearchFieldTypeTag,\n\t\t},\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res4) // >>> OK\n\n\tres5, err := rdb.JSONSet(ctx, \"key:1\", \"$\",\n\t\tmap[string]interface{}{\n\t\t\t\"email\": \"test@redis.com\",\n\t\t},\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res5) // >>> OK\n\n\n\tres6, err := rdb.FTSearch(ctx, \"idx:email\",\n\t\t\"@email:{test\\\\@redis\\\\.com}\",\n\t).Result()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(res6.Total) // >>> 1",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex12",
      "language": "java",
      "code": "List<FieldArgs<String>> emailSchema = Arrays\n                    .asList(TagFieldArgs.<String> builder().name(\"$.email\").as(\"email\").build());\n            CreateArgs<String, String> emailCreateArgs = CreateArgs.<String, String> builder().on(CreateArgs.TargetType.JSON)\n                    .withPrefix(\"key:\").build();\n\n            CompletableFuture<SearchReply<String, String>> emailResults = asyncCommands\n                    .ftCreate(\"idx:email\", emailCreateArgs, emailSchema).thenCompose(res -> {\n                        System.out.println(res); // >>> OK\n                        return asyncCommands.jsonSet(\"key:1\", JsonPath.ROOT_PATH,\n                                parser.createJsonObject().put(\"email\", parser.createJsonValue(\"\\\"test@redis.com\\\"\")));\n                    }).thenCompose(res2 -> {\n                        System.out.println(res2); // >>> OK\n                        return asyncCommands.ftSearch(\"idx:email\", \"@email:{test\\\\@redis\\\\.com}\");\n                    }).thenApply(res3 -> {\n                        System.out.println(res3.getResults().size()); // >>> 1\n                        System.out.println(res3.getResults().get(0).getId());\n                        // >>> key:1\n                        return res3;\n                    }).toCompletableFuture();",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex13",
      "language": "java",
      "code": "List<FieldArgs<String>> emailSchema = Arrays\n                    .asList(TagFieldArgs.<String> builder().name(\"$.email\").as(\"email\").build());\n\n            CreateArgs<String, String> emailCreateArgs = CreateArgs.<String, String> builder().on(CreateArgs.TargetType.JSON)\n                    .withPrefix(\"key:\").build();\n\n            Mono<Void> emailResults = reactiveCommands.ftCreate(\"idx:email\", emailCreateArgs, emailSchema).doOnNext(res -> {\n                System.out.println(res); // >>> OK\n            }).flatMap(res -> reactiveCommands.jsonSet(\"key:1\", JsonPath.ROOT_PATH,\n                    parser.createJsonObject().put(\"email\", parser.createJsonValue(\"\\\"test@redis.com\\\"\")))).doOnNext(res -> {\n                        System.out.println(res); // >>> OK\n                    }).flatMap(res -> reactiveCommands.ftSearch(\"idx:email\", \"@email:{test\\\\@redis\\\\.com}\")).doOnNext(res -> {\n                        System.out.println(res.getResults().size()); // >>> 1\n                        System.out.println(res.getResults().get(0).getId());\n                        // >>> key:1\n                    }).then();",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex14",
      "language": "java",
      "code": "SchemaField[] emailSchema = {\n            TextField.of(\"$.email\").as(\"email\")\n        };\n\n        jedis.ftCreate(\"idx:email\", \n            new FTCreateParams()\n                    .addPrefix(\"key:\")\n                    .on(IndexDataType.JSON),\n            emailSchema\n        );\n\n        jedis.jsonSet(\"key:1\", Path2.ROOT_PATH, \"{\\\"email\\\": \\\"test@redis.com\\\"}\");\n        \n        SearchResult res4 = jedis.ftSearch(\"idx:email\",\n            RediSearchUtil.escapeQuery(\"@email{test@redis.com}\"),\n            new FTSearchParams().dialect(2)\n        );\n        System.out.println(res4.getTotalResults());",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex15",
      "language": "javascript",
      "code": "await client.ft.create('idx:email', {\n  '$.email': {\n    type: SCHEMA_FIELD_TYPE.TAG,\n    AS: 'email'\n  }\n}, {\n  ON: 'JSON',\n  PREFIX: 'key:'\n})\n\nawait client.json.set('key:1', '$', { email: 'test@redis.com' });\n\ntry {\n    const res6 = await client.ft.search('idx:email', 'test@redis.com', { DIALECT: 2 });\n    console.log(res6);\n} catch (err) {\n    console.log(\"'test@redis.com' syntax not yet supported.\");\n}",
      "section_id": "tag-field"
    },
    {
      "id": "tag-field-ex16",
      "language": "python",
      "code": "schema = (\n    TagField(\"$.email\", as_name=\"email\")\n)\n\nidx_email = r.ft(\"idx:email\")\nidx_email.create_index(\n    schema,\n    definition=IndexDefinition(prefix=[\"key:\"], index_type=IndexType.JSON),\n)\nr.json().set('key:1', Path.root_path(), '{\"email\": \"test@redis.com\"}')\n\ntry:\n    res = idx_email.search(Query(\"test@redis.com\").dialect(2))\n    print(res)\nexcept Exception:\n    print(\"'test@redis.com' syntax not yet supported.\")",
      "section_id": "tag-field"
    },
    {
      "id": "full-text-field-ex0",
      "language": "plaintext",
      "code": "FT.SEARCH index \"@field:\\\"phrase\\\"\"",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex1",
      "language": "plaintext",
      "code": "> FT.SEARCH idx:bicycle \"@description:\\\"rough terrain\\\"\"\n1) (integer) 1\n2) \"bicycle:8\"\n3) 1) \"$\"\n   2) \"{\\\"pickup_zone\\\":\\\"POLYGON((1.9450 41.4301, 2.4018 41.4301, 2.4018 41.1987, 1.9450 41.1987, 1.9450 41.4301))\\\",\\\"store_location\\\":\\\"2.1734, 41.3851\\\",\\\"brand\\\":\\\"nHill\\\",\\\"model\\\":\\\"Summit\\\",\\\"price\\\":1200,\\\"description\\\":\\\"This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\\xe2\\x80\\x99re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.\\\",\\\"condition\\\":\\\"new\\\"}\"",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex2",
      "language": "csharp",
      "code": "SearchResult res5 = db.FT().Search(\n            \"idx:bicycle\",\n            new(\"@description:\\\"rough terrain\\\"\")\n        );\n        Console.WriteLine(res5.TotalResults);   // >>> 1",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex3",
      "language": "go",
      "code": "res7, err := rdb.FTSearch(ctx,\n\t\t\"idx:bicycle\", \"@description:\\\"rough terrain\\\"\",\n\t).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res7.Total) // >>> 1\n\n\tfor _, doc := range res7.Docs {\n\t\tfmt.Println(doc.ID)\n\t}\n\t// >>> bicycle:8",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex4",
      "language": "java",
      "code": "CompletableFuture<SearchReply<String, String>> textMatchResults = asyncCommands\n                    .ftSearch(\"idx:bicycle\", \"@description:\\\"rough terrain\\\"\").thenApply(res -> {\n                        res.getResults().forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:8\n\n                        return res;\n                    }).toCompletableFuture();",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex5",
      "language": "java",
      "code": "Mono<SearchReply<String, String>> textMatchResults = reactiveCommands\n                    .ftSearch(\"idx:bicycle\", \"@description:\\\"rough terrain\\\"\").doOnNext(res -> {\n                        res.getResults().forEach(doc -> {\n                            System.out.printf(\"ID: %s\\n\", doc.getId());\n                        });\n                        // >>> ID: bicycle:8\n                    });",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex6",
      "language": "java",
      "code": "SearchResult res5 = jedis.ftSearch(\"idx:bicycle\",\n            \"@description:\\\"rough terrain\\\"\"\n        );\n        System.out.println(res5.getTotalResults()); // >>> 1\n\n        List<Document> docs5 = res5.getDocuments();\n\n        for (int i = 0; i < docs5.size(); i++) {\n            System.out.println(docs5.get(i).getId());\n        }\n        // >>> bicycle:8",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex7",
      "language": "javascript",
      "code": "const res7 = await client.ft.search('idx:bicycle', '@description:\"rough terrain\"');\nconsole.log(res7.total); // >>> 1 (Result{1 total, docs: [Document {'id': 'bicycle:8'...)",
      "section_id": "full-text-field"
    },
    {
      "id": "full-text-field-ex8",
      "language": "python",
      "code": "res = index.search(Query(\"@description:\\\"rough terrain\\\"\"))\nprint(res.total)\n# >>> 1 (Result{1 total, docs: [Document {'id': 'bicycle:8'...)",
      "section_id": "full-text-field"
    }
  ]
}
