{"id":9023,"date":"2020-08-04T07:00:04","date_gmt":"2020-08-04T14:00:04","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=9023"},"modified":"2025-06-13T23:42:32","modified_gmt":"2025-06-14T06:42:32","slug":"arrays-in-json-modeling-querying-and-indexing","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/","title":{"rendered":"Arrays in JSON: Modeling, Querying and Indexing Performance"},"content":{"rendered":"<blockquote><p><span style=\"font-weight: 400\">Array is <strong>THE<\/strong> difference between the relational model and the JSON model.\u00a0 \u00a0&#8212; <a href=\"https:\/\/twitter.com\/N1QL\/status\/804472885096026112\">Gerald Sangudi<\/a><\/span><\/p><\/blockquote>\n<h4>Abstract<\/h4>\n<p>JSON array gives you flexibility in the type of elements,\u00a0 number of elements, size of the elements, and the depth of the elements.\u00a0 This adds to the flexibility of operational JSON databases like Couchbase and MongoDB. The performance of queries with an array predicate in operational databases depends on the array indexes. However, the array indexes in these databases come with significant <a href=\"https:\/\/docs.mongodb.com\/manual\/core\/index-multikey\/#limitations\">limitations.<\/a> E.g. only one array key is allowed per index. The array indexes, even when created, can only process AND predicates efficiently.\u00a0 The upcoming Couchbase 6.6 release removes these JSON limitations by using a built-in inverted index to be used to index and query arrays in N1QL.\u00a0 This article explains the background and the workings of this novel implementation.<\/p>\n<h4>Introduction<\/h4>\n<p>An array is a basic type built into <a href=\"https:\/\/www.json.org\/json-en.html\">JSON<\/a>\u00a0defined as\u00a0<em>An\u00a0<i>array<\/i>\u00a0is an ordered collection of values. An array begins with\u00a0<tt>[<\/tt><small>left bracket<\/small>\u00a0and ends with\u00a0<tt>]<\/tt><small>right bracket<\/small>. Values are separated by\u00a0<tt>,<\/tt><small>comma<\/small>.\u00a0<\/em>An array gives you flexibility because it can contain an arbitrary number of scalar, vector, and object values. A user profile can have an array of hobbies, a customer profile an array of cars, a member profile an array of friends. Couchbase N1QL provides a <a href=\"https:\/\/www.slideshare.net\/journalofinformix\/utilizing-arrays\">rich set of operators<\/a> to manipulate arrays; MongoDB has a list of <a href=\"https:\/\/docs.mongodb.com\/manual\/tutorial\/query-arrays\/\">operators to handle arrays<\/a> as well.<\/p>\n<p><span style=\"font-weight: 400\">Before you start querying, you need to model your data in arrays. All JSON document databases like Couchbase, MongoDB recommend you to denormalize your data model to improve your performance and appdev. What that means is, transform your 1:N relationship into a single document by embedded the N into 1.\u00a0 In JSON, you\u2019d do that by using an array.\u00a0 The example below, the document(1) contains 8 (N) likes. Instead of storing a foreign key reference to another table, in JSON, we store data inline.\u00a0<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 whitespace-before:2 whitespace-after:1 lang:js decode:true\">            \"public_likes\": [\r\n                \"Julius Tromp I\",\r\n                \"Corrine Hilll\",\r\n                \"Jaeden McKenzie\",\r\n                \"Vallie Ryan\",\r\n                \"Brian Kilback\",\r\n                \"Lilian McLaughlin\",\r\n                \"Ms. Moses Feeney\",\r\n                \"Elnora Trantow\"\r\n            ],<\/pre>\n<p><span style=\"font-weight: 400\">Values here are arrays of strings. In JSON, each element can be any valid JSON type: scalars (numeric, string, etc), or objects or vectors (arrays).\u00a0 Each hotel document contains an array of reviews.\u00a0 This is the process of denormalization.\u00a0 Converting multiple 1:N relationships to a single hotel object that contains N public_likes and M reviews.\u00a0 With this, the hotel object embeds two arrays: public_likes and reviews.\u00a0 There can be any number of values of any type under these arrays.\u00a0 This is the key contributing factor to JSON Schema flexibility.\u00a0 When you need to add new likes or reviews, you simply add a new value or an object to this.\u00a0<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 whitespace-before:2 whitespace-after:1 lang:js decode:true \">  \"reviews\": [\r\n                {\r\n                    \"author\": \"Ozella Sipes\",\r\n                    \"content\": \"This was our 2nd trip here...\",\r\n                    \"date\": \"2013-06-22 18:33:50 +0300\",\r\n                    \"ratings\": {\r\n                        \"Cleanliness\": 5,\r\n                        \"Location\": 4,\r\n                        \"Overall\": 4,\r\n                        \"Rooms\": 3,\r\n                        \"Service\": 5,\r\n                        \"Value\": 4\r\n                    }\r\n                },\r\n                {\r\n                    \"author\": \"Barton Marks\",\r\n                    \"content\": \"We found the hotel ...\",\r\n                    \"date\": \"2015-03-02 19:56:13 +0300\",\r\n                    \"ratings\": {\r\n                        \"Business service (e.g., internet access)\": 4,\r\n                        \"Check in \/ front desk\": 4,\r\n                        \"Cleanliness\": 4,\r\n                        \"Location\": 4,\r\n                        \"Overall\": 4,\r\n                        \"Rooms\": 3,\r\n                        \"Service\": 3,\r\n                        \"Value\": 5\r\n                    }\r\n                }\r\n            ],\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Like the hotel object above, you denormalize your data model into JSON, there could be many arrays for each object. Profiles have arrays for hobbies, cars, credit cards, preferences, etc.\u00a0 each of these can be scalars (simple numeric\/string\/boolean values) or vectors (arrays of other scalars, arrays of objects, etc).\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">Once you model and store the data, you need to process it &#8212; select, join, project. Couchbase <\/span><a href=\"https:\/\/www.couchbase.com\/products\/n1ql\/\"><span style=\"font-weight: 400\">N1QL<\/span><\/a><span style=\"font-weight: 400\"> (SQL for JSON) provides an expressive language to do these and more. \u00a0 Here are common use cases.<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 wrap:true whitespace-before:02 whitespace-after:02 lang:mysql decode:true\" title=\"USE CASE 1.\">1. Find all the documents with a simple value can be done by either of the following queries.\r\n\r\nSELECT *\r\nFROM `travel-sample`\r\nWHERE type = \"hotel\"\r\n    AND ANY p IN public_likes SATISFIES p = \"Vallie Ryan\" END\r\n\r\n\r\nSELECT t\r\nFROM `travel-sample` t\r\n      UNNEST t.public_likes AS p\r\nWHERE t.type = \"hotel\"\r\n    AND p = \"Vallie Ryan\"\r\n<\/pre>\n<pre class=\"theme:eclipse font-size:17 line-height:20 wrap:true whitespace-before:02 whitespace-after:02 lang:mysql decode:true\" title=\"USE CASE 2.\">2. Find all the documents that match a range.  In this case, we try to find all the documents that have atleast one rating has \u201cOverall\u201d &gt; 4\r\n\r\nSELECT COUNT(1)\r\nFROM `travel-sample`\r\nWHERE type = \"hotel\"\r\n    AND ANY r IN reviews SATISFIES r.ratings.Overall &gt; 4 END\r\n\r\nSELECT COUNT(1) \r\nFROM `travel-sample` t\r\nUNNEST reviews AS r\r\nWHERE t.type = \"hotel\"\r\n    AND r.ratings.Overall &gt; 4\r\nGROUP BY t.type\r\n\r\n<\/pre>\n<pre class=\"theme:eclipse font-size:17 line-height:20 height-set:true wrap:true whitespace-before:02 whitespace-after:02 lang:default mark:1 decode:true \" title=\"USE CASE 3.\">3. Find all the documents where every rating for  \u201cOverall\u201d &gt; 4\r\n\r\nSELECT * FROM `travel-sample` WHERE type = \u2018hotel\u2019 AND ANY AND EVERY r in reviews SATISFIES r.Overall &gt; 4 END\r\n\r\nSELECT COUNT(1)\r\nFROM `travel-sample`\r\nWHERE type = \"hotel\"\r\n    AND ANY\r\n    AND EVERY r IN reviews SATISFIES r.ratings.Overall &gt; 4 END\r\n\r\nSELECT reviews[*].ratings[*].Overall\r\nFROM `travel-sample`\r\nWHERE type = \"hotel\"\r\n    AND ANY\r\n    AND EVERY r IN reviews SATISFIES r.ratings.Overall &gt; 4 END\r\nlimit 10;\r\n\r\n\t[\r\n    {\r\n        \"Overall\": [\r\n            5\r\n        ],\r\n        \"name\": \"The Bulls Head\"\r\n    },\r\n    {\r\n        \"Overall\": [\r\n            5,\r\n            5,\r\n            5,\r\n            5,\r\n            5\r\n        ],\r\n        \"name\": \"La Pradella\"\r\n    },\r\n    {\r\n        \"Overall\": [\r\n            5,\r\n            5,\r\n            5\r\n        ],\r\n        \"name\": \"Culloden House Hotel\"\r\n    },\r\n    {\r\n        \"Overall\": [\r\n            5\r\n        ],\r\n        \"name\": \"Auberge-Camping Bagatelle\"\r\n    },\r\n    {\r\n        \"Overall\": [\r\n            5,\r\n            5\r\n        ],\r\n        \"name\": \"Avignon Hotel Monclar\"\r\n    }\r\n    ]\r\n<\/pre>\n<h4>Array Indexing:<\/h4>\n<p><span style=\"font-weight: 400\">Indexing arrays are a challenge for B-tree based indexes.\u00a0 However, the JSON database has to do it to meet the performance requirements: <\/span><a href=\"https:\/\/docs.mongodb.com\/manual\/core\/index-multikey\/\"><span style=\"font-weight: 400\">MongoDB does it<\/span><\/a><span style=\"font-weight: 400\">; <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/indexing-arrays.html\"><span style=\"font-weight: 400\">Couchbase does it<\/span><\/a><span style=\"font-weight: 400\">. However, both come with limitations.\u00a0 You can only have one array key within an index.\u00a0 This is<\/span><a href=\"https:\/\/docs.mongodb.com\/manual\/core\/index-multikey\/#limitations\"><span style=\"font-weight: 400\"> true of MongoDB<\/span><\/a><span style=\"font-weight: 400\">; this is <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/indexing-arrays.html#syntax\"><span style=\"font-weight: 400\">true of Couchbase N1QL<\/span><\/a><span style=\"font-weight: 400\">.\u00a0 The core reason for this limitation is when you index elements of an array, you need separate index entries.\u00a0\u00a0<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 wrap:true whitespace-before:02 whitespace-after:02 lang:js decode:true\" title=\"Array indexing use B-TREE based index\">Consider the array:\r\n\r\nDocument key: \u201cbob\u201d\r\n{\r\n   \u201cId\u201d: \u201cbob123\u201d\r\n   \u201cA\u201d: [1, 2, 3, 4]\r\n   \u201cB\u201d: [521, 4892, 284]\r\n}\r\n\r\nIndexing of the field \u201cid\u201d  simply requires 1 entry in the index:   \r\n         \u201cbob123\u201d:bob\r\n\r\nIndexing of the field \u201ca\u201d requires 4 entries in the index: \r\n        \u201c1\u201d:\u201dbob\u201d, 2:\u201dbob\u201d, 3:\u201dbob\u201d, 4:\u201dbob\u201d\r\n\r\nIndexing of the composite index (id, a) requires 4 entries:\r\n   \u201cbob123\u201d, 1: bob\r\n   \u201cbob123\u201d, 2: bob\r\n   \u201cbob123\u201d, 3: bob\r\n   \u201cbob123\u201d, 4: bob\r\n\r\nIndexing of the composite index (id, a, b) requires the following 12 entries:\r\n   \u201cbob123\u201d, 1, 521: bob\r\n   \u201cbob123\u201d, 1,4982: bob\r\n   \u201cbob123\u201d, 1, 284: bob\r\n   \u201cbob123\u201d, 2, 521: bob\r\n   \u201cbob123\u201d, 2,4982: bob\r\n   \u201cbob123\u201d, 2, 284: bob\r\n   \u201cbob123\u201d, 3, 521: bob\r\n   \u201cbob123\u201d, 3,4982: bob\r\n   \u201cbob123\u201d, 3, 284: bob\r\n   \u201cbob123\u201d, 4, 521: bob\r\n   \u201cbob123\u201d, 4,4982: bob\r\n   \u201cbob123\u201d, 4, 284: bob\r\n<\/pre>\n<p><span style=\"font-weight: 400\">The size of the index grows exponentially as the number of array keys in the index and the number of array elements in the index.\u00a0 \u00a0 Hence the limitation. \u00a0 Implications of this limitation are:\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Push only one array predicate to the index scan and handle other predicates after the index scan.<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">This means queries with multiple array predicates could be slow<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Avoid composite indexes with array keys to avoid huge indexes.<\/span>\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">This means queries with complex predicates on array keys will be slow<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>Good news from the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Out_of_left_field\">LEFT FIELD<\/a>.<\/h4>\n<p><span style=\"font-weight: 400\">The full-text search index was designed to handle text pattern search based on relevance. \u00a0 The way it does by tokenizing each field.\u00a0 In this example below, each document is analyzed to get tokens:<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 wrap:true whitespace-before:02 whitespace-after:02 lang:js decode:true\" title=\"Sample Text Tokenization\">\u201cdoc:1\u201d-&gt;\u201ddesc\u201d:   {\u201cdesc\u201d: \u201can appel a day, keeps the doctor away.\u201d}\r\n\u201cdoc:2\u201d-&gt;\u201ddesc\u201d: {\u201cdesc\u201d:\u201dan appel a day, keeps Billl Gates away.\u201d}\r\n\u201cdoc:3\u201d-&gt;\u201ddesc\u201d: {\u201cdesc\u201d: \u201can apple a dday, keeps the apple farmer rich.\u201d}\r\n\r\n\u201cdoc:1\u201d-&gt;\u201ddesc\u201d: [\u201capple\u201d, \u201cday\u201d, \u201ckeep\u201d, \u201cdoctor\u201d, \u201caway\u201d]\r\n\u201cdoc:2\u201d-&gt;\u201ddesc\u201d: [\u201capple\u201d, \u201cday\u201d, \u201ckeep\u201d, \u201cbill\u201d, \u201cgates\u201d,  \u201caway\u201d]\r\n\u201cdoc:3\u201d-&gt;\u201ddesc\u201d: [\u201capple\u201d, \u201cday\u201d, \u201ckeep\u201d, \u201cfarmer\u201d, \u201crich\u201d]\r\n\r\nThis then is combined to get a single array of tokens:\r\n\r\n[\u201capple\u201d, \u201caway\u201d, \u201cbill\u201d, \u201cday\u201d, \u201cdoctor\u201d, \u201cfarmer\u201d, \u201cgates\u201d, \u201ckeep\u201d, \u201crich\u201d]\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400\">For each token, it keeps the list of documents that token is present.\u00a0 This is the inverted tree structure! Unlike a B-Tree based index, it avoids repeating the same token value N number of times, one for each document it\u2019s present in.\u00a0 When you have millions or billions of documents, this is a huge saving.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">The second thing to note here is, the inverted index used for <\/span><b>an ARRAY OF TOKENS!<\/b><span style=\"font-weight: 400\">\u00a0 \u00a0 In fact, the inverted tree structure in the full-text-search is ideal for indexing and searching for array values, especially when these values have duplicates.\u00a0 <\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9042\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM-300x91.png\" alt=\"\" width=\"583\" height=\"177\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM-300x91.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM-1024x312.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM-768x234.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM-20x6.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.46.27-PM.png 1242w\" sizes=\"auto, (max-width: 583px) 100vw, 583px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400\">Indexing arrays using the inverted index will be the same process, except there\u2019s no tokenization. Let\u2019s revisit indexing our document \u201cbob\u201d, with additional documents, \u201cSam\u201d and \u201cNeill\u201d<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 wrap:true whitespace-before:02 whitespace-after:02 lang:js decode:true\" title=\"Sample Documents\">Document key: \u201cbob\u201d\r\n{\r\n   id\u201d: \u201cbob123\u201d\r\n   \u201ca\u201d: [1, 2, 3, 4]\r\n  \u201cb\u201d: [521, 4892, 284]\r\n}\r\nDocument key: \u201csam\u201d\r\n{\r\n   \u201cid\u201d: \u201csam456\u201d\r\n   \u201ca\u201d: [1,3, 4, 9]\r\n  \u201cb\u201d: [521, 232, 284]\r\n}\r\nDocument key: \u201cneil\u201d\r\n{\r\n   \u201cid\u201d: \u201cneil987\u201d\r\n   \u201cA\u201d[1, 2, 4, 6]\r\n  \u201cb\u201d: [521, 4892, 543]\r\n}\r\n\r\n<\/pre>\n<p>The <a href=\"https:\/\/docs.couchbase.com\/server\/current\/fts\/full-text-intro.html\">Couchbase FTS<\/a> has an analyzer called a <a href=\"https:\/\/docs.couchbase.com\/server\/current\/fts\/fts-using-analyzers.html#pre-constructed-analyzers\">keyword analyzer<\/a>. This indexes the values as-is instead of trying to find its root by stemming it. Basically, value is the token.\u00a0 For array value indexing, we can use this index and exploit the efficiencies of an inverted index.\u00a0 Let&#8217;s construct an FTS index on the documents bob, sam, neil.\u00a0 <span style=\"font-weight: 400\">In the case of the inverted tree, each field gets its own inverted tree: one each for id, a, and b.\u00a0 Because these are individual trees, they don\u2019t grow exponentially as the B-tree composite index. The number of index entries is proportional to the number of unique items in each field.\u00a0 In this case, we have <strong>14 entries<\/strong> for the 3 documents with three fields of a total of 24 values.\u00a0 Creating a B-tree index on (id, a, b) for the same document will create <strong>36 entries! <\/strong><\/span><\/p>\n<p><span style=\"color: #0000ff\">Notice that for three documents with two index entries the difference is 157%. As the number of documents, the number of arrays increases, the savings using an inverted index increase as well.<\/span><\/p>\n<div id=\"attachment_9043\" style=\"width: 753px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-9043\" class=\" wp-image-9043\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-300x170.png\" alt=\"Inverted index on three fields.\" width=\"743\" height=\"421\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-300x170.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-1024x580.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-768x435.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-1536x871.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM-1320x748.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-2.58.36-PM.png 1842w\" sizes=\"auto, (max-width: 743px) 100vw, 743px\" \/><\/a><p id=\"caption-attachment-9043\" class=\"wp-caption-text\">Inverted index on three fields.<\/p><\/div>\n<p><span style=\"font-weight: 400\">However, we do have an issue.\u00a0 <\/span><span style=\"font-weight: 400\">How you process predicates?<\/span><\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 whitespace-before:02 whitespace-after:02 lang:mysql decode:true\">WHERE\u00a0 id between \"ada\" and \"tate\"\r\n       AND ANY\u00a0 x IN a SATISFIES x = 3 END\r\n       AND ANY y in b SATISFIES y = 521 END<\/pre>\n<p>The B-Tree index stores all of the values in (id, a, and b) together, the inverted index in FTS has distinct trees for each field. So, applying multiple predicates is not so easy.\u00a0 This is true for our array processing as well as text processing.\u00a0 It&#8217;s common in text processing to ask questions like: search for all <span style=\"color: #0000ff\">Californian <span style=\"color: #ff0000\">residents<\/span><\/span>\u00a0with <span style=\"color: #0000ff\">skiing<\/span> as their <span style=\"color: #ff0000\">hobby<\/span>.<\/p>\n<p>To process this, FTS applies the predicate on each field individually to get the list of document-keys for each predicate.\u00a0 It then applies the boolean predicate <span style=\"color: #0000ff\">AND<\/span> on top of it. This layer uses the famed <a href=\"https:\/\/roaringbitmap.org\/\">roaring bitmap package<\/a> to create and process the bitmap of document ids to finalize the result.\u00a0 \u00a0Yes, there is extra processing here compared to a simpler B-TREE based index, but this makes it possible to index many arrays and process the query in a reasonable time.<a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM.png\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9045\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM-300x235.png\" alt=\"\" width=\"694\" height=\"545\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM-300x235.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM-1024x802.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM-768x602.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM-20x16.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/Screen-Shot-2020-08-03-at-3.41.36-PM.png 1054w\" sizes=\"auto, (max-width: 694px) 100vw, 694px\" \/><\/a><\/p>\n<h4>Inverted Tree:\u00a0 A tree that keeps on giving!<\/h4>\n<p>The B-Tree composite index combines the scanning and the AND predicate application.\u00a0 \u00a0The inverted tree approach separates the two.\u00a0 Index and scanning each field is different from processing the composite predicate.\u00a0 Because of this separation,\u00a0 the bitmap layer can process OR, NOT predicates along with AND predicates.\u00a0 Changing the AND in the previous example to OR is simply an instruction to the bitmap processing on the document qualification and deduplication<\/p>\n<pre class=\"theme:eclipse font-size:17 line-height:20 whitespace-before:02 whitespace-after:02 lang:mysql decode:true \">WHERE\u00a0 id BETWEEN \"ada\" AND \"tate\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0OR ANY\u00a0 x IN a SATISFIES x = 3 END\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0OR ANY y in b SATISFIES y = 521 END<b><\/b><\/pre>\n<h4>COUCHBASE Release:<\/h4>\n<p>Couchbase 6.6 will support using FTS indexes for processing complex array predicates.\u00a0 This improves the TCO of array handling, enables developers and designers to use, index, query arrays as needed without limitations. Look for upcoming announcements, documentation, feature blogs, etc.<\/p>\n<h4>References<\/h4>\n<ol>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/working-json-arrays-n1ql\/\">Working with JSON Arrays in N1QL<\/a><\/li>\n<li><a href=\"https:\/\/www.slideshare.net\/journalofinformix\/utilizing-arrays\">Utilizing Arrays: Modeling, Querying, and Indexing<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/collectionops.html\">Couchbase N1QL Collection Operators<\/a><\/li>\n<li><a href=\"https:\/\/docs.mongodb.com\/manual\/tutorial\/query-arrays\/\">MongoDB: Query an arrray<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/fts\/full-text-intro.html\">Couchbase FTS<\/a><\/li>\n<li><a href=\"https:\/\/learn.couchbase.com\/store\/509465-cb121-intro-to-couchbase-full-text-search-fts\">FREE: Couchbase interactive training<\/a><\/li>\n<li>FTS BLogs:\u00a0 <a href=\"https:\/\/www.couchbase.com\/blog\/tag\/fts\/\">https:\/\/www.couchbase.com\/blog\/tag\/fts\/<\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/collectionops.html\"><span style=\"font-weight: 400\">Collection operators<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/indexing-arrays.html\"><span style=\"font-weight: 400\">ARRAY indexing<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/making-the-most-of-your-arrays-with-array-indexing\/\"><span style=\"font-weight: 400\">Making most of your arrays&#8230;with N1QL Array Indexing<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/www.couchbase.com\/blog\/1.making-most-of-your-arrays..-with-covering-array-indexes-and-more\/\"><span style=\"font-weight: 400\">Making most of your Arrays.. with Covering Array Indexes and more.<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/services-and-indexes\/indexes\/indexing-and-query-perf.html#array-index\"><span style=\"font-weight: 400\">Couchbase Indexing<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/dzone.com\/articles\/nesting-and-unnesting-in-couchbase-n1ql\"><span style=\"font-weight: 400\">NEST and UNNEST: Normalizing and Denormalizing JSON on the Fly<\/span><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Array is THE difference between the relational model and the JSON model.\u00a0 \u00a0&#8212; Gerald Sangudi Abstract JSON array gives you flexibility in the type of elements,\u00a0 number of elements, size of the elements, and the depth of the elements.\u00a0 This [&hellip;]<\/p>\n","protected":false},"author":55,"featured_media":9024,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1821,1819,2165,1812],"tags":[1865,1840,1572,1696,1261,1725],"ppma_author":[8929],"class_list":["post-9023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-architecture","category-data-modeling","category-full-text-search","category-n1ql-query","tag-array","tag-array-index","tag-database","tag-indexing","tag-json","tag-nosql-database"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Arrays in JSON: Modeling, Querying + Indexing Performance<\/title>\n<meta name=\"description\" content=\"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Arrays in JSON: Modeling, Querying and Indexing Performance\" \/>\n<meta property=\"og:description\" content=\"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-04T14:00:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:42:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1440\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Keshav Murthy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rkeshavmurthy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keshav Murthy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\"},\"author\":{\"name\":\"Keshav Murthy\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\"},\"headline\":\"Arrays in JSON: Modeling, Querying and Indexing Performance\",\"datePublished\":\"2020-08-04T14:00:04+00:00\",\"dateModified\":\"2025-06-14T06:42:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\"},\"wordCount\":1387,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg\",\"keywords\":[\"array\",\"Array Index\",\"database\",\"Indexing\",\"JSON\",\"NoSQL Database\"],\"articleSection\":[\"Application Design\",\"Couchbase Architecture\",\"Data Modeling\",\"Full-Text Search\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\",\"name\":\"Arrays in JSON: Modeling, Querying + Indexing Performance\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg\",\"datePublished\":\"2020-08-04T14:00:04+00:00\",\"dateModified\":\"2025-06-14T06:42:32+00:00\",\"description\":\"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg\",\"width\":2560,\"height\":1440,\"caption\":\"An array of houses. Bay farm island, Alameda, California\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Arrays in JSON: Modeling, Querying and Indexing Performance\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\",\"name\":\"Keshav Murthy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g\",\"caption\":\"Keshav Murthy\"},\"description\":\"Keshav Murthy is a Vice President at Couchbase R&amp;D. Previously, he was at MapR, IBM, Informix, Sybase, with more than 20 years of experience in database design &amp; development. He lead the SQL and NoSQL R&amp;D team at IBM Informix. He has received two President's Club awards at Couchbase, two Outstanding Technical Achievement Awards at IBM. Keshav has a bachelor's degree in Computer Science and Engineering from the University of Mysore, India, holds eleven US patents and has four US patents pending.\",\"sameAs\":[\"https:\/\/blog.planetnosql.com\/\",\"https:\/\/x.com\/rkeshavmurthy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/keshav-murthy\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Arrays in JSON: Modeling, Querying + Indexing Performance","description":"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/","og_locale":"en_US","og_type":"article","og_title":"Arrays in JSON: Modeling, Querying and Indexing Performance","og_description":"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.","og_url":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/","og_site_name":"The Couchbase Blog","article_published_time":"2020-08-04T14:00:04+00:00","article_modified_time":"2025-06-14T06:42:32+00:00","og_image":[{"width":2560,"height":1440,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg","type":"image\/jpeg"}],"author":"Keshav Murthy","twitter_card":"summary_large_image","twitter_creator":"@rkeshavmurthy","twitter_misc":{"Written by":"Keshav Murthy","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/"},"author":{"name":"Keshav Murthy","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636"},"headline":"Arrays in JSON: Modeling, Querying and Indexing Performance","datePublished":"2020-08-04T14:00:04+00:00","dateModified":"2025-06-14T06:42:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/"},"wordCount":1387,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg","keywords":["array","Array Index","database","Indexing","JSON","NoSQL Database"],"articleSection":["Application Design","Couchbase Architecture","Data Modeling","Full-Text Search","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/","url":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/","name":"Arrays in JSON: Modeling, Querying + Indexing Performance","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg","datePublished":"2020-08-04T14:00:04+00:00","dateModified":"2025-06-14T06:42:32+00:00","description":"Find out how Couchbase 6.6 removes limitations on JSON arrays by using a built-in inverted index to be used to index and query arrays in N1QL.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/08\/IMG_20200726_200132-scaled.jpg","width":2560,"height":1440,"caption":"An array of houses. Bay farm island, Alameda, California"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/arrays-in-json-modeling-querying-and-indexing\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Arrays in JSON: Modeling, Querying and Indexing Performance"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636","name":"Keshav Murthy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4e51d72fc07c662aa791316deafffac4","url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","caption":"Keshav Murthy"},"description":"Keshav Murthy is a Vice President at Couchbase R&amp;D. Previously, he was at MapR, IBM, Informix, Sybase, with more than 20 years of experience in database design &amp; development. He lead the SQL and NoSQL R&amp;D team at IBM Informix. He has received two President's Club awards at Couchbase, two Outstanding Technical Achievement Awards at IBM. Keshav has a bachelor's degree in Computer Science and Engineering from the University of Mysore, India, holds eleven US patents and has four US patents pending.","sameAs":["https:\/\/blog.planetnosql.com\/","https:\/\/x.com\/rkeshavmurthy"],"url":"https:\/\/www.couchbase.com\/blog\/author\/keshav-murthy\/"}]}},"authors":[{"term_id":8929,"user_id":55,"is_guest":0,"slug":"keshav-murthy","display_name":"Keshav Murthy","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/af74df754db27152971d0aed2f323ead5a1f9fe5afd0209af91e12e784451224?s=96&d=mm&r=g","author_category":"","last_name":"Murthy","first_name":"Keshav","job_title":"","user_url":"https:\/\/blog.planetnosql.com\/","description":"Keshav Murthy is a Vice President at Couchbase R&amp;D. Previously, he was at MapR, IBM, Informix, Sybase, with more than 20 years of experience in database design &amp; development. He lead the SQL and NoSQL R&amp;D team at IBM Informix. He has received two President's Club awards at Couchbase, two Outstanding Technical Achievement Awards at IBM. Keshav has a bachelor's degree in Computer Science and Engineering from the University of Mysore, India,  holds ten US patents and has three US patents pending."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/9023","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=9023"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/9023\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/9024"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=9023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=9023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=9023"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=9023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}