{"id":1873,"date":"2015-01-27T16:54:18","date_gmt":"2015-01-27T16:54:17","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1873"},"modified":"2015-01-27T16:54:18","modified_gmt":"2015-01-27T16:54:17","slug":"manual-secondary-indexes","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/","title":{"rendered":"Data modelling: manual secondary indexes"},"content":{"rendered":"<p>We often describe Couchbase Server as a document database. That&#39;s a good description: Couchbase performs superbly as a JSON document store.<\/p>\n<p>When modelling our data for Couchbase Server, though, it can help to think of it more like a key-value store.<\/p>\n<h2>Key-value thinking versus document thinking<\/h2>\n<p>So, what&#39;s the practical difference between key-value stores and document stores? Mostly, it&#39;s about how you query the data.<\/p>\n<p>Key-value databases tend to store data as opaque units, giving you one index: the key itself. You store and retrieve data as discreet chunks using only the key. That&#39;s usually fast because it&#39;s uncomplicated but it&#39;s also a pretty blunt tool.<\/p>\n<p>Document stores, on the other hand, give you additional indexes on the data inside the document and so you have much greater freedom in how you query that data. Of course, query\u00a0in any database system\u00a0comes with a resource\u00a0cost.<\/p>\n<p>When designing our data model, we need to choose which approach to take. To do that we need to understand the trade-offs.<\/p>\n<h2>The trade-offs<\/h2>\n<p>Couchbase is equally at home giving you key-value access and document query-style access to your data.<\/p>\n<p>Both approaches have their advantages and their trade-offs:<\/p>\n<table border=\"1\" cellpadding=\"5\" cellspacing=\"5\" style=\"width: 500px;\">\n<thead>\n<tr>\n<th scope=\"col\"><strong>Key-value access advantages<\/strong><\/th>\n<th scope=\"col\"><strong>Document-style access advantages<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Super-fast: sub-millisecond responses<\/td>\n<td>Flexibility: easily create new indexes any time<\/td>\n<\/tr>\n<tr>\n<td>Immediately consistent within the cluster<\/td>\n<td>\n<p>Insight: create views that deal with changing data and can provide analytical insight rather than just another index<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>Tiny resource impact<\/td>\n<td>See inside the document: create indexes on KV pairs inside your JSON<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>With Couchbase views today and soon <a href=\"https:\/\/n1ql.couchbase.com\">N1QL<\/a>, querying in Couchbase gives you enormous flexibility. Once N1QL is generally available, and the indexing to support it, perhaps much of this blog will be obsolete.<\/p>\n<p>However, right now\u00a0we can keep all the benefits of Couchbase&#39;s key-value model \u2013 immediate consistency, cached sub-millisecond response times, linear scaling profile, etc \u2013 without giving up much\u00a0query flexibility. The way we do that is to create manual secondary indexes.<\/p>\n<h2>It&#39;s all about the look-up<\/h2>\n<p>Imagine we&#39;re storing user profiles in Couchbase. The first choice we need to make is how we key them.<\/p>\n<p>Let&#39;s say our users log-in to our system using their email address. That means that, at the minimum, when someone logs in we know that one thing about them. If we key our user profiles by email address, then we get a log-in process something like this:<\/p>\n<ol>\n<li>User enters her email address (e.g. lily@example.com)\u00a0and password into the log-in form.<\/li>\n<li>We GET the document from Couchbase that has the key\u00a0<em>lily@couchbase.com<\/em><\/li>\n<li>We verify the password against the hash in the user profile.<\/li>\n<li>If successful, we complete the log-in and Lily goes about her business.<\/li>\n<\/ol>\n<p>Great, that was easy.<\/p>\n<p>After a while, Lily changes her email address and wants to update it in our system. Naturally, she&#39;ll want to use her updated email address to log in.<\/p>\n<p>We have three options for how to handle this:<\/p>\n<ul>\n<li>create an entirely new user profile document, keyed by the new email address, and destroy the old one<\/li>\n<li>create a redirect\u00a0document<\/li>\n<li>from the beginning, use look-up documents to create a manual secondary index.<\/li>\n<\/ul>\n<p>The first option seems a little inelegant. For example, if we had been referring to the document elsewhere in our system then those references would now be dead-ends.<\/p>\n<h3>Redirects<\/h3>\n<p>We could, instead, take the second option and create a new document keyed by the new email address. The document contents would simply be the old email address. Of course, we&#39;d also need to place the new email address inside the user profile document itself so that we wouldn&#39;t need the look-up document to associate that email address with this user.<\/p>\n<p>Now our login process would look like this:<\/p>\n<ol>\n<li>User enters her email address (e.g. lily@newdomain.com)\u00a0and password into the log-in form.<\/li>\n<li>We GET the document from Couchbase that has the key\u00a0<span style=\"font-family: sans-serif, Arial, Verdana, 'Trebuchet MS'; line-height: 20.7999992370605px; text-align: left;\">lily@newdomain.com.<\/span><\/li>\n<li><span style=\"font-family: sans-serif, Arial, Verdana, 'Trebuchet MS'; line-height: 20.7999992370605px; text-align: left;\">We see that the document is another email address (lily@example.com), rather than a full user profile.<\/span><\/li>\n<li><span style=\"font-family: sans-serif, Arial, Verdana, 'Trebuchet MS'; line-height: 20.7999992370605px; text-align: left;\">We GET the document lily@example.com.<\/span><\/li>\n<li>We verify the password against the hash in the user profile.<\/li>\n<li>If successful, we complete the log-in and Lily goes about her business.<\/li>\n<\/ol>\n<p>This could work. It gives us a little complication, though: we no longer know what we&#39;ll receive when we do a GET on an email address.<\/p>\n<p>Instead, we could start out using look-up documents from the very beginning.<\/p>\n<h3>Using a manual secondary index<\/h3>\n<p>It&#39;s quite likely that some portion of our userbase will change their email address during their account&#39;s lifetime. So, it makes sense for us to handle this probability right from the beginning.<\/p>\n<p>Rather than key our users&#39;\u00a0profile documents with their email addresses, we should key them\u00a0with something else unique that&#39;ll remain constant. As we&#39;re looking for something unchanging, the key itself should ideally be unrelated to anything about\u00a0the users themselves. Couchbase Server gives us an easy way to handle this: atomic counters.<\/p>\n<p>We can call atomic counters with either an increment or a decrement, plus an amount, and then we get the resulting number back. If we increment the counter by one each time we create a new user profile, that gives us\u00a0a unique and unchanging key.<\/p>\n<p>Let&#39;s look at how it works:<\/p>\n<ol>\n<li>Our user completes the sign-up process.<\/li>\n<li>We increment the counter and it gives us back 1001.<\/li>\n<li>We create our user profile document using the key 1001.<\/li>\n<\/ol>\n<p>Now changes in the user&#39;s profile do not affect the key. There&#39;s a problem, though: unless we want to make our users memorise a numeric username \u2013 such as 1001 \u2013 then we have to find another way of matching a friendly username with the user&#39;s profile.<\/p>\n<p>That&#39;s where our manual secondary index comes in. Let&#39;s add another\u00a0step\u00a0to our sign-up process:<\/p>\n<ol start=\"4\">\n<li>We create a look-up document keyed on the user&#39;s email address, with a value of 1001.<\/li>\n<\/ol>\n<p>Now, our log-in process looks like this:<\/p>\n<ol style=\"font-family: sans-serif, Arial, Verdana, 'Trebuchet MS'; line-height: 20.7999992370605px; text-align: left;\">\n<li>User enters her email address (e.g. lily@newdomain.com)\u00a0and password into the log-in form.<\/li>\n<li>We GET the document from Couchbase that has the key\u00a0<span style=\"line-height: 20.7999992370605px;\">lily@newdomain.com.<\/span><\/li>\n<li>We see the value of that document is 1001, so we GET the user profile document with the key 1001.<\/li>\n<li>We verify the password against the hash in the user profile.<\/li>\n<li>If successful, we complete the log-in and Lily goes about her business.<\/li>\n<\/ol>\n<p>With most database systems, that could introduce an unacceptable lag but with Couchbase the additional look-up should be sub-millisecond. That opens up a whole range of other manual indexes we could introduce: Twitter handles, phone numbers, cities and so on.<\/p>\n<p>Of course, in introduces a little more work in the application layer but, in return, we get the flexibility of secondary indexes while retaining all the speed and scalability that made us choose Couchbase Server in the first place.<\/p>\n<p>Next time I&#39;ll be looking at key naming.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We often describe Couchbase Server as a document database. That&#39;s a good description: Couchbase performs superbly as a JSON document store. When modelling our data for Couchbase Server, though, it can help to think of it more like a key-value [&hellip;]<\/p>\n","protected":false},"author":18,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8982],"class_list":["post-1873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"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>Data modelling: manual secondary indexes - The Couchbase Blog<\/title>\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\/manual-secondary-indexes\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Data modelling: manual secondary indexes\" \/>\n<meta property=\"og:description\" content=\"We often describe Couchbase Server as a document database. That&#039;s a good description: Couchbase performs superbly as a JSON document store. When modelling our data for Couchbase Server, though, it can help to think of it more like a key-value [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-01-27T16:54:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\"},\"author\":{\"name\":\"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/6c3060a94353df62a71d4672b3454555\"},\"headline\":\"Data modelling: manual secondary indexes\",\"datePublished\":\"2015-01-27T16:54:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\"},\"wordCount\":1171,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\",\"name\":\"Data modelling: manual secondary indexes - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-01-27T16:54:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Data modelling: manual secondary indexes\"}]},{\"@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\/6c3060a94353df62a71d4672b3454555\",\"name\":\"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/b1bc555cd9166b46d6063003c3b92317\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3b38ea45b78371f0008a765ea828bfed91aa97c25981ebf214226402a510b39b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3b38ea45b78371f0008a765ea828bfed91aa97c25981ebf214226402a510b39b?s=96&d=mm&r=g\",\"caption\":\"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase\"},\"description\":\"Matthew Revell is a Lead Dev Advocate, EMEA Couchbase. He developed a global strategy for putting Couchbase front in the minds of the product's developers.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/matthew-revell\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Data modelling: manual secondary indexes - The Couchbase Blog","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\/manual-secondary-indexes\/","og_locale":"en_US","og_type":"article","og_title":"Data modelling: manual secondary indexes","og_description":"We often describe Couchbase Server as a document database. That&#39;s a good description: Couchbase performs superbly as a JSON document store. When modelling our data for Couchbase Server, though, it can help to think of it more like a key-value [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-01-27T16:54:17+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/"},"author":{"name":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/6c3060a94353df62a71d4672b3454555"},"headline":"Data modelling: manual secondary indexes","datePublished":"2015-01-27T16:54:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/"},"wordCount":1171,"commentCount":4,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/","url":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/","name":"Data modelling: manual secondary indexes - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-01-27T16:54:17+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/manual-secondary-indexes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Data modelling: manual secondary indexes"}]},{"@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\/6c3060a94353df62a71d4672b3454555","name":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/b1bc555cd9166b46d6063003c3b92317","url":"https:\/\/secure.gravatar.com\/avatar\/3b38ea45b78371f0008a765ea828bfed91aa97c25981ebf214226402a510b39b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3b38ea45b78371f0008a765ea828bfed91aa97c25981ebf214226402a510b39b?s=96&d=mm&r=g","caption":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase"},"description":"Matthew Revell is a Lead Dev Advocate, EMEA Couchbase. He developed a global strategy for putting Couchbase front in the minds of the product's developers.","url":"https:\/\/www.couchbase.com\/blog\/author\/matthew-revell\/"}]}},"authors":[{"term_id":8982,"user_id":18,"is_guest":0,"slug":"matthew-revell","display_name":"Matthew Revell, Lead Developer Advocate, EMEA, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/3b38ea45b78371f0008a765ea828bfed91aa97c25981ebf214226402a510b39b?s=96&d=mm&r=g","author_category":"","last_name":"Revell","first_name":"Matthew","job_title":"","user_url":"","description":"Matthew Revell is a Lead Dev Advocate, EMEA Couchbase. He developed a global strategy for putting Couchbase front in the minds of the product's developers."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1873","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\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1873"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1873\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1873"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}