{
  "schema_version": 2,
  "id": "develop/clients/jedis/vecsearch",
  "title": "Index and query vectors",
  "url": "https://redis.io/docs/latest/develop/clients/jedis/vecsearch/",
  "summary": "Learn how to index and query vector embeddings with Redis",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-10-16T16:44:30+01:00",
  "page_type": "content",
  "content_hash": "72aaffc80964a5ffc7b9d0f7de3a6b6bc28e51eb54aceb33c67dede80173b041",
  "sections": [
    {
      "id": "initialize",
      "title": "Initialize",
      "role": "content",
      "text": "If you are using [Maven](https://maven.apache.org/), add the following\ndependencies to your `pom.xml` file:\n\n[code example]\n\nIf you are using [Gradle](https://gradle.org/), add the following\ndependencies to your `build.gradle` file:\n\n[code example]"
    },
    {
      "id": "import-dependencies",
      "title": "Import dependencies",
      "role": "content",
      "text": "Import the following classes in your source file:\n\nFoundational: Import required libraries for vector embeddings, Redis operations, and search functionality\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "define-a-helper-method",
      "title": "Define a helper method",
      "role": "content",
      "text": "The embedding model represents the vectors as an array of `float` values,\nwhich is the format required by Redis Search.\nAlso, when you store vectors in a hash object, you must encode the vector\narray as a `byte` string. To simplify this situation, you can declare a helper\nmethod `floatsToByteString()` that takes the `float` array that the\nembedding model returns and encodes it as a `byte` string:\n\nFoundational: Create a helper method to convert float arrays to binary strings for vector storage in hash objects\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "create-a-tokenizer-instance",
      "title": "Create a tokenizer instance",
      "role": "content",
      "text": "The next step is to generate the embeddings using the\n[`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)\nmodel. The vectors that represent the\nembeddings have 384 components, regardless of the length of the input\ntext, but note that the input is truncated to 256\ntokens (see\n[Word piece tokenization](https://huggingface.co/learn/nlp-course/en/chapter6/6)\n\nPractical pattern: Initialize a tokenizer and embedding model for generating vector representations from text\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "create-the-index",
      "title": "Create the index",
      "role": "content",
      "text": "Connect to Redis and delete any index previously created with the\nname `vector_idx`. (The `ftDropIndex()` call throws an exception if\nthe index doesn't already exist, which is why you need the\n`try...catch` block.)\n\nFoundational: Connect to Redis and clean up existing vector indexes\n\n**Difficulty:** Beginner\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nNext, create the index.\nThe schema in the example below includes three fields: the text content to index, a\n[tag](https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/tags)\nfield to represent the \"genre\" of the text, and the embedding vector generated from\nthe original text content. The `embedding` field specifies\n[HNSW](https://redis.io/docs/latest/develop/ai/search-and-query/vectors#hnsw-index)\nindexing, the\n[L2](https://redis.io/docs/latest/develop/ai/search-and-query/vectors#distance-metrics)\nvector distance metric, `Float32` values to represent the vector's components,\nand 384 dimensions, as required by the `all-MiniLM-L6-v2` embedding model.\n\nThe `FTCreateParams` object specifies hash objects for storage and a\nprefix `doc:` that identifies the hash objects to index.\n\nFoundational: Create a vector search index for hash documents with HNSW algorithm and L2 distance metric\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]"
    },
    {
      "id": "add-data",
      "title": "Add data",
      "role": "content",
      "text": "You can now supply the data objects, which will be indexed automatically\nwhen you add them with [`hset()`](https://redis.io/docs/latest/commands/hset), as long as\nyou use the `doc:` prefix specified in the index definition.\n\nUse the `predict()` method of the `Predictor` object\nas shown below to create the embedding that represents the `content` field.\nThe `predict()` method returns a `float[]` array which is then converted to a `byte`\nstring using the helper method. Use the `byte` string representation when you are\nindexing hash objects (as in this example), but use the array of `float` directly for\nJSON objects (see [Differences with JSON objects](#differences-with-json-documents)\nbelow). Note that when you set the `embedding` field, you must use an overload\nof `hset()` that requires `byte` arrays for each of the key, the field name, and\nthe value, which is why you must include the `getBytes()` calls on the strings.\n\nFoundational: Store hash documents with vector embeddings generated from text content\n\n**Difficulty:** Beginner\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 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. As with `hset()`, use the overload of\n`himportSet()` that takes `byte` arrays so that you can pass the binary embedding.\nUse a [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 with vector embeddings as compact hashes using a HashImport fieldset and a pipeline of HIMPORT SET calls\n\n**Difficulty:** Intermediate\n\n**Builds upon:** add_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.\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": "run-a-query",
      "title": "Run a query",
      "role": "content",
      "text": "After you have created the index and added the data, you are ready to run a query.\nTo do this, you must create another embedding vector from your chosen query\ntext. Redis calculates the vector distance between the query vector and each\nembedding vector in the index as it runs the query. You can request the results to be\nsorted to rank them in order of ascending distance.\n\nThe code below creates the query embedding using the `predict()` method, as with\nthe indexing, and passes it as a parameter when the query executes (see\n[Vector search](https://redis.io/docs/latest/develop/ai/search-and-query/query/vector-search)\nfor more information about using query parameters with embeddings).\nThe query is a\n[K nearest neighbors (KNN)](https://redis.io/docs/latest/develop/ai/search-and-query/vectors#knn-vector-search)\nsearch that sorts the results in order of vector distance from the query vector.\n\nVector similarity search: Find semantically similar documents by comparing query embeddings with indexed vectors using L2 distance\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nAssuming you have added the code from the steps above to your source file,\nit is now ready to run, but note that it may take a while to complete when\nyou run it for the first time (which happens because the tokenizer must download the\n`all-MiniLM-L6-v2` model data before it can\ngenerate the embeddings). When you run the code, it outputs the following result text:\n\n[code example]\n\nThe exact distances may differ slightly on your system.\n\nNote that the results are ordered according to the value of the `distance`\nfield, with the lowest distance indicating the greatest similarity to the query.\nAs expected, the text *\"That is a very happy person\"*\nis the result judged to be most similar in meaning to the query text\n*\"That is a happy person\"*."
    },
    {
      "id": "differences-with-json-documents",
      "title": "Differences with JSON documents",
      "role": "content",
      "text": "Indexing JSON documents is similar to hash indexing, but there are some\nimportant differences. JSON allows much richer data modeling with nested fields, so\nyou must supply a [path](https://redis.io/docs/latest/develop/data-types/json/path) in the schema\nto identify each field you want to index. However, you can declare a short alias for each\nof these paths (using the `as()` option) to avoid typing it in full for\nevery query. Also, you must specify `IndexDataType.JSON` when you create the index.\n\nThe code below shows these differences, but the index is otherwise very similar to\nthe one created previously for hashes:\n\nFoundational: Create a vector search index for JSON documents with JSON paths and field aliases\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nAn important difference with JSON indexing is that the vectors are\nspecified using arrays of `float` instead of binary strings, so you don't need\na helper method to convert the array to a binary string.\n\nUse [`jsonSet()`](https://redis.io/docs/latest/commands/json.set) to add the data\ninstead of [`hset()`](https://redis.io/docs/latest/commands/hset). Use instances\nof `JSONObject` to supply the data instead of `Map`, as you would for\nhash objects.\n\nFoundational: Store JSON documents with vector embeddings as arrays (different from hash binary format)\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 is almost identical to the one for the hash documents. This\ndemonstrates how the right choice of aliases for the JSON paths can\nsave you having to write complex queries. An important thing to notice\nis that the vector parameter for the query is still specified as a\nbinary string (created using the `floatsToByteString()` method), even though\nthe data for the `embedding` field of the JSON was specified as an array.\n\nVector similarity search: Query JSON documents using vector embeddings with field aliases for simplified syntax\n\n**Difficulty:** Intermediate\n\n**Available in:** Java (Synchronous - Jedis)\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n\n\nApart from the `jdoc:` prefixes for the keys, the result from the JSON\nquery is the same as for hash:\n\n[code example]"
    },
    {
      "id": "learn-more",
      "title": "Learn more",
      "role": "related",
      "text": "See\n[Vector search](https://redis.io/docs/latest/develop/ai/search-and-query/query/vector-search)\nfor more information about the indexing options, distance metrics, and query format\nfor vectors."
    }
  ],
  "examples": [
    {
      "id": "initialize-ex0",
      "language": "xml",
      "code": "<dependency>\n    <groupId>redis.clients</groupId>\n    <artifactId>jedis</artifactId>\n    <version>8.0.2</version>\n</dependency>\n<dependency>\n    <groupId>ai.djl.huggingface</groupId>\n    <artifactId>tokenizers</artifactId>\n    <version>0.33.0</version>\n</dependency>\n<dependency>\n    <groupId>ai.djl.pytorch</groupId>\n    <artifactId>pytorch-model-zoo</artifactId>\n    <version>0.33.0</version>\n</dependency>\n<dependency>\n    <groupId>ai.djl</groupId>\n    <artifactId>api</artifactId>\n    <version>0.33.0</version>\n</dependency>",
      "section_id": "initialize"
    },
    {
      "id": "initialize-ex1",
      "language": "bash",
      "code": "implementation 'redis.clients:jedis:8.0.2'\nimplementation 'ai.djl.huggingface:tokenizers:0.33.0'\nimplementation 'ai.djl.pytorch:pytorch-model-zoo:0.33.0'\nimplementation 'ai.djl:api:0.33.0'",
      "section_id": "initialize"
    },
    {
      "id": "import-dependencies-ex0",
      "language": "java",
      "code": "import redis.clients.jedis.HashImport;\nimport redis.clients.jedis.Pipeline;\nimport redis.clients.jedis.RedisClient;\nimport redis.clients.jedis.search.*;\nimport redis.clients.jedis.search.schemafields.*;\nimport redis.clients.jedis.search.schemafields.VectorField.VectorAlgorithm;\nimport redis.clients.jedis.exceptions.JedisDataException;\nimport redis.clients.jedis.json.Path2;\n\nimport org.json.JSONObject;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.util.Map;\nimport java.util.List;\n\n// DJL classes for model loading and inference.\nimport ai.djl.huggingface.translator.TextEmbeddingTranslatorFactory;\nimport ai.djl.inference.Predictor;\nimport ai.djl.repository.zoo.Criteria;\nimport ai.djl.training.util.ProgressBar;",
      "section_id": "import-dependencies"
    },
    {
      "id": "define-a-helper-method-ex0",
      "language": "java",
      "code": "public static byte[] floatsToByteString(float[] floats) {\n        byte[] bytes = new byte[Float.BYTES * floats.length];\n        ByteBuffer\n            .wrap(bytes)\n            .order(ByteOrder.LITTLE_ENDIAN)\n            .asFloatBuffer()\n            .put(floats);\n        return bytes;\n    }",
      "section_id": "define-a-helper-method"
    },
    {
      "id": "create-a-tokenizer-instance-ex0",
      "language": "java",
      "code": "Predictor<String, float[]> predictor = null;\n\n        try {\n            Criteria<String, float[]> criteria = Criteria.builder().setTypes(String.class, float[].class)\n                    .optModelUrls(\"djl://ai.djl.huggingface.pytorch/sentence-transformers/all-MiniLM-L6-v2\")\n                    .optEngine(\"PyTorch\").optTranslatorFactory(new TextEmbeddingTranslatorFactory())\n                    .optProgress(new ProgressBar()).build();\n\n            predictor = criteria.loadModel().newPredictor();\n        } catch (Exception e) {\n            // ...\n        }",
      "section_id": "create-a-tokenizer-instance"
    },
    {
      "id": "create-the-index-ex0",
      "language": "java",
      "code": "RedisClient jedis = RedisClient.create(\"redis://localhost:6379\");\n        \n        try {jedis.ftDropIndex(\"vector_idx\");} catch (JedisDataException j){}",
      "section_id": "create-the-index"
    },
    {
      "id": "create-the-index-ex1",
      "language": "java",
      "code": "SchemaField[] schema = {\n            TextField.of(\"content\"),\n            TagField.of(\"genre\"),\n            VectorField.builder()\n                .fieldName(\"embedding\")\n                .algorithm(VectorAlgorithm.HNSW)\n                .attributes(\n                    Map.of(\n                        \"TYPE\", \"FLOAT32\",\n                        \"DIM\", 384,\n                        \"DISTANCE_METRIC\", \"L2\"\n                    )\n                )\n                .build()\n        };\n        \n        jedis.ftCreate(\"vector_idx\",\n            FTCreateParams.createParams()\n                .addPrefix(\"doc:\")\n                .on(IndexDataType.HASH),\n                schema\n        );",
      "section_id": "create-the-index"
    },
    {
      "id": "add-data-ex0",
      "language": "java",
      "code": "String sentence1 = \"That is a very happy person\";\n        byte[] embedding1;\n\n        try {\n            embedding1 = floatsToByteString(predictor.predict(sentence1));\n        } catch (Exception e) {\n            // This just allows the code to compile without errors.\n            // In a real-world scenario, you would handle the exception properly.\n            embedding1 = new byte[384 * Float.BYTES];\n        }\n\n        jedis.hset(\"doc:1\", Map.of(  \"content\", sentence1, \"genre\", \"persons\"));\n        jedis.hset(\"doc:1\".getBytes(), \"embedding\".getBytes(), embedding1);\n        \n        String sentence2 = \"That is a happy dog\";\n        byte[] embedding2;\n\n        try {\n            embedding2 = floatsToByteString(predictor.predict(sentence2));\n        } catch (Exception e) {\n            embedding2 = new byte[384 * Float.BYTES];\n        }\n        \n        jedis.hset(\"doc:2\", Map.of(  \"content\", sentence2, \"genre\", \"pets\"));\n        jedis.hset(\"doc:2\".getBytes(), \"embedding\".getBytes(), embedding2);\n\n        String sentence3 = \"Today is a sunny day\";\n        byte[] embedding3;\n\n        try {\n            embedding3 = floatsToByteString(predictor.predict(sentence3));\n        } catch (Exception e) {\n            embedding3 = new byte[384 * Float.BYTES];\n        }\n\n        Map<String, String> doc3 = Map.of(  \"content\", sentence3, \"genre\", \"weather\");\n        jedis.hset(\"doc:3\", doc3);\n        jedis.hset(\"doc:3\".getBytes(), \"embedding\".getBytes(), embedding3);",
      "section_id": "add-data"
    },
    {
      "id": "bulk-import-with-himport-ex0",
      "language": "java",
      "code": "String[][] docData = {\n            {\"doc:1\", \"That is a very happy person\", \"persons\"},\n            {\"doc:2\", \"That is a happy dog\", \"pets\"},\n            {\"doc:3\", \"Today is a sunny day\", \"weather\"}\n        };\n\n        try (HashImport fields = HashImport.of(\"content\", \"genre\", \"embedding\");\n                Pipeline pipeline = jedis.pipelined()) {\n            for (String[] doc : docData) {\n                byte[] docEmbedding;\n\n                try {\n                    docEmbedding = floatsToByteString(predictor.predict(doc[1]));\n                } catch (Exception e) {\n                    docEmbedding = new byte[384 * Float.BYTES];\n                }\n\n                pipeline.himportSet(doc[0].getBytes(), fields,\n                        doc[1].getBytes(), doc[2].getBytes(), docEmbedding);\n            }\n            pipeline.sync();\n        }",
      "section_id": "bulk-import-with-himport"
    },
    {
      "id": "run-a-query-ex0",
      "language": "java",
      "code": "String sentence = \"That is a happy person\";\n        byte[] embedding;\n\n        try {\n            embedding = floatsToByteString(predictor.predict(sentence));\n        } catch (Exception e) {\n            embedding = new byte[384 * Float.BYTES];\n        }\n        \n        int K = 3;\n        Query q = new Query(\"*=>[KNN $K @embedding $BLOB AS distance]\").\n                            returnFields(\"content\", \"distance\").\n                            addParam(\"K\", K).\n                            addParam(\"BLOB\", embedding)\n                            .setSortBy(\"distance\", true)\n                            .dialect(2);\n\n        // Execute the query\n        List<Document> docs = jedis.ftSearch(\"vector_idx\", q).getDocuments();\n        System.out.println(\"Results:\");\n        \n        for (Document doc: docs) {\n            System.out.println(\n                String.format(\n                    \"ID: %s, Distance: %s, Content: %s\",\n                    doc.getId(),\n                    doc.get(\"distance\"),\n                    doc.get(\"content\")\n                )\n            );\n        }",
      "section_id": "run-a-query"
    },
    {
      "id": "run-a-query-ex1",
      "language": "plaintext",
      "code": "Results:\nID: doc:1, Distance: 0.114169836044, Content: That is a very happy person\nID: doc:2, Distance: 0.610845506191, Content: That is a happy dog\nID: doc:3, Distance: 1.48624765873, Content: Today is a sunny day",
      "section_id": "run-a-query"
    },
    {
      "id": "differences-with-json-documents-ex0",
      "language": "java",
      "code": "SchemaField[] jsonSchema = {\n            TextField.of(\"$.content\").as(\"content\"),\n            TagField.of(\"$.genre\").as(\"genre\"),\n            VectorField.builder()\n                .fieldName(\"$.embedding\").as(\"embedding\")\n                .algorithm(VectorAlgorithm.HNSW)\n                .attributes(\n                    Map.of(\n                        \"TYPE\", \"FLOAT32\",\n                        \"DIM\", 384,\n                        \"DISTANCE_METRIC\", \"L2\"\n                    )\n                )\n                .build()\n        };\n        \n        jedis.ftCreate(\"vector_json_idx\",\n            FTCreateParams.createParams()\n                .addPrefix(\"jdoc:\")\n                .on(IndexDataType.JSON),\n                jsonSchema\n        );",
      "section_id": "differences-with-json-documents"
    },
    {
      "id": "differences-with-json-documents-ex1",
      "language": "java",
      "code": "String jSentence1 = \"That is a very happy person\";\n\n        float[] jEmbedding1;\n\n        try {\n            jEmbedding1 = predictor.predict(jSentence1);\n        } catch (Exception e) {\n            // This just allows the code to compile without errors.\n            // In a real-world scenario, you would handle the exception properly.\n            jEmbedding1 = new float[384];\n        }\n\n        JSONObject jdoc1 = new JSONObject()\n                .put(\"content\", jSentence1)\n                .put(\"genre\", \"persons\")\n                .put(\n                    \"embedding\",\n                    jEmbedding1\n                );\n\n        jedis.jsonSet(\"jdoc:1\", Path2.ROOT_PATH, jdoc1);\n\n        String jSentence2 = \"That is a happy dog\";\n\n        float[] jEmbedding2;\n\n        try {\n            jEmbedding2 = predictor.predict(jSentence2);\n        } catch (Exception e) {\n            jEmbedding2 = new float[384];\n        }\n\n        JSONObject jdoc2 = new JSONObject()\n                .put(\"content\", jSentence2)\n                .put(\"genre\", \"pets\")\n                .put(\n                    \"embedding\",\n                    jEmbedding2\n                );\n        \n        jedis.jsonSet(\"jdoc:2\", Path2.ROOT_PATH, jdoc2);\n\n        String jSentence3 = \"Today is a sunny day\";\n\n        float[] jEmbedding3;\n\n        try {\n            jEmbedding3 = predictor.predict(jSentence3);\n        } catch (Exception e) {\n            jEmbedding3 = new float[384];\n        }\n\n        JSONObject jdoc3 = new JSONObject()\n                .put(\"content\", jSentence3)\n                .put(\"genre\", \"weather\")\n                .put(\n                    \"embedding\",\n                    jEmbedding3\n                );\n\n        jedis.jsonSet(\"jdoc:3\", Path2.ROOT_PATH, jdoc3);",
      "section_id": "differences-with-json-documents"
    },
    {
      "id": "differences-with-json-documents-ex2",
      "language": "java",
      "code": "String jSentence = \"That is a happy person\";\n        byte[] jEmbedding;\n\n        try {\n            jEmbedding = floatsToByteString(predictor.predict(jSentence));\n        } catch (Exception e) {\n            jEmbedding = new byte[384 * Float.BYTES];\n        }\n\n        int jK = 3;\n        Query jq = new Query(\"*=>[KNN $K @embedding $BLOB AS distance]\").\n                            returnFields(\"content\", \"distance\").\n                            addParam(\"K\", jK).\n                            addParam(\n                                \"BLOB\",\n                                jEmbedding\n                            )\n                            .setSortBy(\"distance\", true)\n                            .dialect(2);\n\n        // Execute the query\n        List<Document> jDocs = jedis\n                .ftSearch(\"vector_json_idx\", jq)\n                .getDocuments();\n\n        System.out.println(\"Results:\");\n        \n        for (Document doc: jDocs) {\n            System.out.println(\n                String.format(\n                    \"ID: %s, Distance: %s, Content: %s\",\n                    doc.getId(),\n                    doc.get(\"distance\"),\n                    doc.get(\"content\")\n                )\n            );\n        }",
      "section_id": "differences-with-json-documents"
    },
    {
      "id": "differences-with-json-documents-ex3",
      "language": "plaintext",
      "code": "Results:\nID: jdoc:1, Distance: 0.114169836044, Content: That is a very happy person\nID: jdoc:2, Distance: 0.610845506191, Content: That is a happy dog\nID: jdoc:3, Distance: 1.48624765873, Content: Today is a sunny day",
      "section_id": "differences-with-json-documents"
    }
  ]
}
