{
  "schema_version": 2,
  "id": "develop/clients/jedis/queryjson",
  "title": "Index and query documents",
  "url": "https://redis.io/docs/latest/develop/clients/jedis/queryjson/",
  "summary": "Learn how to use Redis Search with JSON and hash documents.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-10-16T16:25:49+01:00",
  "page_type": "content",
  "content_hash": "d16b757c7205e1031b51f31671769d296eafa33a7536a81b0f64a3301df027d9",
  "sections": [
    {
      "id": "initialize",
      "title": "Initialize",
      "role": "content",
      "text": "Make sure that you have [Redis Open Source](https://redis.io/docs/latest/operate/oss_and_stack)\nor another Redis server available. Also install the\n[Jedis](https://redis.io/docs/latest/develop/clients/jedis) client library if you\nhaven't already done so.\n\nAdd the following dependencies. All of them are applicable to both JSON and hash,\nexcept for the `Path` and `JSONObject` classes, which are specific to JSON (see\n[Path](https://redis.io/docs/latest/develop/data-types/json/path) for a description of the\nJSON path syntax).\n\nFoundational: Import required Jedis classes for JSON indexing and query operations\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "create-data",
      "title": "Create data",
      "role": "content",
      "text": "Create some test data to add to the database:\n\nFoundational: Define sample user data structures for indexing and querying\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "add-the-index",
      "title": "Add the index",
      "role": "content",
      "text": "Connect to your Redis database. The code below shows the most\nbasic connection but see\n[Connect to the server](https://redis.io/docs/latest/develop/clients/jedis/connect)\nto learn more about the available connection options.\n\nFoundational: Establish a connection to a Redis server for query operations\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nDelete any existing index called `idx:users` and any keys that start with `user:`.\n\nFoundational: Clean up existing indexes and data before creating new indexes\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nCreate an index. In this example, only JSON documents with the key prefix `user:` are indexed. For more information, see [Query syntax](https://redis.io/docs/latest/develop/ai/search-and-query/query).\n\nFoundational: Create a search index for JSON documents with field definitions and key prefix filtering\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "add-the-data",
      "title": "Add the data",
      "role": "content",
      "text": "Add the three sets of user data to the database as\n[JSON](https://redis.io/docs/latest/develop/data-types/json) objects.\nIf you use keys with the `user:` prefix then Redis will index the\nobjects automatically as you add them:\n\nFoundational: Store JSON documents in Redis with automatic indexing based on key prefix\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "query-the-data",
      "title": "Query the data",
      "role": "content",
      "text": "You can now use the index to search the JSON objects. The\n[query](https://redis.io/docs/latest/develop/ai/search-and-query/query)\nbelow searches for objects that have the text \"Paul\" in any field\nand have an `age` value in the range 30 to 40:\n\nQuery with filters: Search JSON documents using text matching and numeric range filters to find specific records\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nSpecify query options to return only the `city` field:\n\nQuery with field projection: Retrieve only specific fields from search results to reduce data transfer\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nUse an\n[aggregation query](https://redis.io/docs/latest/develop/ai/search-and-query/query/aggregation)\nto count all users in each city.\n\nAggregation query: Group and count results by field values to analyze data patterns\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "differences-with-hash-documents",
      "title": "Differences with hash documents",
      "role": "content",
      "text": "Indexing for hash documents is very similar to JSON indexing but you\nneed to specify some slightly different options.\n\nWhen you create the schema for a hash index, you don't need to\nadd aliases for the fields, since you use the basic names to access\nthe fields anyway. Also, you must use `IndexDataType.HASH` for the `On()`\noption of `FTCreateParams` when you create the index. The code below shows these\nchanges with a new index called `hash-idx:users`, which is otherwise the same as\nthe `idx:users` index used for JSON documents in the previous examples.\n\nFirst, delete any existing index called `hash-idx:users` and any keys that start with `huser:`.\n\nFoundational: Clean up existing hash indexes and data before creating new indexes\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nNow create the new index:\n\nFoundational: Create a search index for hash documents with field definitions and key prefix filtering\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nUse [`hset()`](https://redis.io/docs/latest/commands/hset) to add the hash\ndocuments instead of [`jsonSet()`](https://redis.io/docs/latest/commands/json.set).\n\nFoundational: Store hash documents in Redis with automatic indexing based on key prefix\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nThe query commands work the same here for hash as they do for JSON (but\nthe name of the hash index is different). The results are returned in\na `List` of `Document` objects, as with JSON:\n\nQuery with filters: Search hash documents using text matching and numeric range filters (same as JSON queries)\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "bulk-import-with-himport",
      "title": "Bulk import with HIMPORT",
      "role": "content",
      "text": "From Redis Open Source 8.10, you can also add the hash documents with the\n[`HIMPORT`](https://redis.io/docs/latest/commands/himport) command family. This creates the same\nhashes as `hset()`, but lets Redis store them as\n[compact hashes](https://redis.io/docs/latest/develop/data-types/hashes#compact-hashes), which use\nless memory when many keys share the same field names. Redis Search indexes\nthese hashes in the same way.\n\nCreate a `HashImport` object with the field names, then create each document\nwith [`himportSet()`](https://redis.io/docs/latest/commands/himport-set), passing only its values,\nin the same order as the field names. Jedis declares the field names with\n[`HIMPORT PREPARE`](https://redis.io/docs/latest/commands/himport-prepare) the first time you use\nthe `HashImport` object on a connection. Use a\n[pipeline](https://redis.io/docs/latest/develop/clients/jedis/transpipe) to send all the\nimports in one round trip:\n\nBulk ingestion: Import hash documents as compact hashes using a HashImport fieldset and a pipeline of HIMPORT SET calls\n\n**Difficulty:** Intermediate\n\n**Builds upon:** add_hash_data\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\n`himportSet()` replaces any existing key, so running this code after the\n`hset()` calls leaves you with the same three documents. The query returns\nthe same result, although the fields can appear in a different order.\n\n> [!NOTE]\n> `HIMPORT` requires Jedis v8.0.0 or later, and Jedis marks its support as\n> experimental, so the API might change. Redis Cloud and Redis Software don't\n> support `HIMPORT`."
    },
    {
      "id": "more-information",
      "title": "More information",
      "role": "content",
      "text": "See the [Redis Search](https://redis.io/docs/latest/develop/ai/search-and-query) docs\nfor a full description of all query features with examples."
    }
  ],
  "examples": [
    {
      "id": "initialize-ex0",
      "language": "java",
      "code": "import redis.clients.jedis.HashImport;\nimport redis.clients.jedis.Pipeline;\nimport redis.clients.jedis.RedisClient;\nimport redis.clients.jedis.Response;\nimport redis.clients.jedis.exceptions.JedisDataException;\nimport redis.clients.jedis.json.Path2;\nimport redis.clients.jedis.search.*;\nimport redis.clients.jedis.search.aggr.*;\nimport redis.clients.jedis.search.schemafields.*;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;",
      "section_id": "initialize"
    },
    {
      "id": "create-data-ex0",
      "language": "java",
      "code": "JSONObject user1 = new JSONObject()\n                .put(\"name\", \"Paul John\")\n                .put(\"email\", \"paul.john@example.com\")\n                .put(\"age\", 42)\n                .put(\"city\", \"London\");\n        \n        JSONObject user2 = new JSONObject()\n                .put(\"name\", \"Eden Zamir\")\n                .put(\"email\", \"eden.zamir@example.com\")\n                .put(\"age\", 29)\n                .put(\"city\", \"Tel Aviv\");\n        \n        JSONObject user3 = new JSONObject()\n                .put(\"name\", \"Paul Zamir\")\n                .put(\"email\", \"paul.zamir@example.com\")\n                .put(\"age\", 35)\n                .put(\"city\", \"Tel Aviv\");",
      "section_id": "create-data"
    },
    {
      "id": "add-the-index-ex0",
      "language": "java",
      "code": "RedisClient jedis = RedisClient.create(\"redis://localhost:6379\");",
      "section_id": "add-the-index"
    },
    {
      "id": "add-the-index-ex1",
      "language": "java",
      "code": "try {jedis.ftDropIndex(\"idx:users\");} catch (JedisDataException j){}\n        jedis.del(\"user:1\", \"user:2\", \"user:3\");",
      "section_id": "add-the-index"
    },
    {
      "id": "add-the-index-ex2",
      "language": "java",
      "code": "SchemaField[] schema = {\n            TextField.of(\"$.name\").as(\"name\"),\n            TextField.of(\"$.city\").as(\"city\"),\n            NumericField.of(\"$.age\").as(\"age\")\n        };\n\n        String createResult = jedis.ftCreate(\"idx:users\",\n            FTCreateParams.createParams()\n                .on(IndexDataType.JSON)\n                .addPrefix(\"user:\"),\n                schema\n        );\n\n        System.out.println(createResult); // >>> OK",
      "section_id": "add-the-index"
    },
    {
      "id": "add-the-data-ex0",
      "language": "java",
      "code": "String user1Set = jedis.jsonSet(\"user:1\", new Path2(\"$\"), user1);\n        String user2Set = jedis.jsonSet(\"user:2\", new Path2(\"$\"), user2);\n        String user3Set = jedis.jsonSet(\"user:3\", new Path2(\"$\"), user3);",
      "section_id": "add-the-data"
    },
    {
      "id": "query-the-data-ex0",
      "language": "java",
      "code": "SearchResult findPaulResult = jedis.ftSearch(\"idx:users\",\n             \"Paul @age:[30 40]\"\n        );\n        \n        System.out.println(findPaulResult.getTotalResults()); // >>> 1\n\n        List<Document> paulDocs = findPaulResult.getDocuments();\n\n        for (Document doc: paulDocs) {\n            System.out.println(doc.getId());\n        }\n        // >>> user:3",
      "section_id": "query-the-data"
    },
    {
      "id": "query-the-data-ex1",
      "language": "java",
      "code": "SearchResult citiesResult = jedis.ftSearch(\"idx:users\",\n            \"Paul\",\n            FTSearchParams.searchParams()\n                .returnFields(\"city\")\n        );\n\n        System.out.println(citiesResult.getTotalResults()); // >>> 2\n\n        for (Document doc: citiesResult.getDocuments()) {\n            System.out.println(doc.getId());\n        }\n        // >>> user:1\n        // >>> user:3",
      "section_id": "query-the-data"
    },
    {
      "id": "query-the-data-ex2",
      "language": "java",
      "code": "AggregationResult aggResult = jedis.ftAggregate(\"idx:users\",\n            new AggregationBuilder(\"*\")\n                .groupBy(\"@city\", Reducers.count().as(\"count\"))\n        );\n\n        System.out.println(aggResult.getTotalResults()); // >>> 2\n\n        for (Row cityRow: aggResult.getRows()) {\n            System.out.printf(\"%s - %d%n\",\n                cityRow.getString(\"city\"), cityRow.getLong(\"count\"));\n        }\n        // >>> London - 1\n        // >>> Tel Aviv - 2",
      "section_id": "query-the-data"
    },
    {
      "id": "differences-with-hash-documents-ex0",
      "language": "java",
      "code": "try {jedis.ftDropIndex(\"hash-idx:users\");} catch (JedisDataException j){}\n        jedis.del(\"huser:1\", \"huser:2\", \"huser:3\");",
      "section_id": "differences-with-hash-documents"
    },
    {
      "id": "differences-with-hash-documents-ex1",
      "language": "java",
      "code": "SchemaField[] hashSchema = {\n            TextField.of(\"name\"),\n            TextField.of(\"city\"),\n            NumericField.of(\"age\")\n        };\n\n        String hashCreateResult = jedis.ftCreate(\"hash-idx:users\",\n            FTCreateParams.createParams()\n                .on(IndexDataType.HASH)\n                .addPrefix(\"huser:\"),\n                hashSchema\n        );\n\n        System.out.println(hashCreateResult); // >>> OK",
      "section_id": "differences-with-hash-documents"
    },
    {
      "id": "differences-with-hash-documents-ex2",
      "language": "java",
      "code": "Map<String, String> user1Info = new HashMap<>();\n        user1Info.put(\"name\", \"Paul John\");\n        user1Info.put(\"email\", \"paul.john@example.com\");\n        user1Info.put(\"age\", \"42\");\n        user1Info.put(\"city\", \"London\");\n        long huser1Set = jedis.hset(\"huser:1\", user1Info);\n        \n        System.out.println(huser1Set); // >>> 4\n\n        Map<String, String> user2Info = new HashMap<>();\n        user2Info.put(\"name\", \"Eden Zamir\");\n        user2Info.put(\"email\", \"eden.zamir@example.com\");\n        user2Info.put(\"age\", \"29\");\n        user2Info.put(\"city\", \"Tel Aviv\");\n        long huser2Set = jedis.hset(\"huser:2\", user2Info);\n        \n        System.out.println(huser2Set); // >>> 4\n\n        Map<String, String> user3Info = new HashMap<>();\n        user3Info.put(\"name\", \"Paul Zamir\");\n        user3Info.put(\"email\", \"paul.zamir@example.com\");\n        user3Info.put(\"age\", \"35\");\n        user3Info.put(\"city\", \"Tel Aviv\");\n        long huser3Set = jedis.hset(\"huser:3\", user3Info);\n        \n        System.out.println(huser3Set); // >>> 4",
      "section_id": "differences-with-hash-documents"
    },
    {
      "id": "differences-with-hash-documents-ex3",
      "language": "java",
      "code": "SearchResult findPaulHashResult = jedis.ftSearch(\"hash-idx:users\",\n             \"Paul @age:[30 40]\"\n        );\n        \n        System.out.println(findPaulHashResult.getTotalResults()); // >>> 1\n\n        List<Document> paulHashDocs = findPaulHashResult.getDocuments();\n\n        for (Document doc: paulHashDocs) {\n            System.out.println(doc.getId());\n        }\n        // >>> huser:3",
      "section_id": "differences-with-hash-documents"
    },
    {
      "id": "bulk-import-with-himport-ex0",
      "language": "java",
      "code": "List<Response<String>> himportRes = new ArrayList<>();\n\n        try (HashImport fields = HashImport.of(\"name\", \"email\", \"age\", \"city\");\n                Pipeline pipeline = jedis.pipelined()) {\n            himportRes.add(pipeline.himportSet(\"huser:1\", fields,\n                    \"Paul John\", \"paul.john@example.com\", \"42\", \"London\"));\n            himportRes.add(pipeline.himportSet(\"huser:2\", fields,\n                    \"Eden Zamir\", \"eden.zamir@example.com\", \"29\", \"Tel Aviv\"));\n            himportRes.add(pipeline.himportSet(\"huser:3\", fields,\n                    \"Paul Zamir\", \"paul.zamir@example.com\", \"35\", \"Tel Aviv\"));\n            pipeline.sync();\n        }",
      "section_id": "bulk-import-with-himport"
    }
  ]
}
