{"id":9601,"date":"2020-11-03T17:55:44","date_gmt":"2020-11-04T01:55:44","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=9601"},"modified":"2025-06-13T18:43:59","modified_gmt":"2025-06-14T01:43:59","slug":"datatabase-query-halloween-problem-n1ql","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/","title":{"rendered":"Halloween Problem: Solution in N1QL."},"content":{"rendered":"<blockquote><p>Learning SQL is easy; Implementing SQL, not so much.<\/p><\/blockquote>\n<p>Halloween has come and gone. But, the tricks of the Halloween problem is here to stay! This has to be solved by databases every day.\u00a0 SQL made the relational database easy, accessible, and successful. SQL may be easy to write, but its implementation hides a lot of complexity.\u00a0 From the days of <a href=\"https:\/\/en.wikipedia.org\/wiki\/IBM_System_R\">System R<\/a> to NoSQL systems, all of us implementing SQL and SQL inspired languages like <a href=\"https:\/\/www.couchbase.com\/products\/n1ql\/\">N1QL<\/a>, have to learn the rules, requirements to ensure the declarative query language continues its <a href=\"https:\/\/www.couchbase.com\/blog\/unreasonable-effectiveness-of-sql\/\">extraordinary effectiveness and correctness.<\/a>\u00a0 One such problem is <a href=\"https:\/\/en.wikipedia.org\/wiki\/Halloween_Problem\">the Halloween Problem<\/a>.\u00a0 I&#8217;ll describe the problem briefly here.\u00a0 I highly recommend reading its <a href=\"https:\/\/web.archive.org\/web\/20070718223542\/https:\/\/www.noncombatant.org\/trove\/fitzpatrick-anecdotes.pdf\">history<\/a> in the IEEE Annals of the history of computing &#8211; second link in the references section below.<\/p>\n<h5><strong>The Problem:<\/strong><\/h5>\n<p>Consider a simple table and index:<\/p>\n<pre class=\"\">CREATE TABLE t (empid int primary key, salary int);\r\nCREATE INDEX i1 ON t(salary);<\/pre>\n<p>Imagine you&#8217;ve loaded some data and the index i1 looks like this. The index entry has the numeric value for the salary, followed by the rowid.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-9604 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-300x42.png\" alt=\"\" width=\"693\" height=\"97\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-300x42.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-1024x144.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-768x108.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-1536x216.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-20x3.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM-1320x186.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.32.29-PM.png 1750w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/a><\/p>\n<p>Now, in the spirit of giving more to people who have it, we want to increase the salary of all the employees who have (salary &gt; 50).<\/p>\n<p><strong>UPDATE t SET salary = salary + 100 WHERE salary &gt; 50; <\/strong><\/p>\n<p><strong>Query Plan: <\/strong>Here&#8217;s the general plan for executing the query.\u00a0 In this case, we&#8217;ll assume the query planner will use the index i1 to qualify the rows) to update.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9605\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-300x101.png\" alt=\"\" width=\"737\" height=\"248\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-300x101.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-1024x344.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-768x258.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-1536x516.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM-1320x444.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-01-at-4.35.58-PM.png 1756w\" sizes=\"auto, (max-width: 737px) 100vw, 737px\" \/><\/a><\/p>\n<p><strong>Query Execution:\u00a0<\/strong>Once this starts to start executing, data rows will be updated and the index will get updated synchronously. the index will look something like this. Each qualified key get updated one by one [we&#8217;re scanning from left to right]. Here&#8217;s the state of the index after updating the initial four entries: <span style=\"font-weight: 400\">(55-&gt;155, 84=&gt;184, 99=&gt;199, 100=&gt;200)<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9618\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-300x64.png\" alt=\"\" width=\"647\" height=\"138\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-300x64.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-1024x219.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-768x164.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-1536x328.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM-1320x282.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-4.38.53-AM.png 1740w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/><\/a><\/p>\n<p>Let&#8217;s see what happens after a couple of more changes.<a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9619\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-300x60.png\" alt=\"\" width=\"660\" height=\"132\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-300x60.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-1024x204.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-768x153.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-1536x306.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-20x4.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM-1320x263.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.00.45-AM.png 1736w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/a><\/p>\n<p class=\"\">As we move to the next item[155,r2] gets updated\u00a0 again\u00a0 to[255,r2].\u00a0 This will repeat updating multiple keys multiple times. That violates the set manipulation rules where the intention is to take the set in the table t and update the qualified salaries by 100.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9621\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-300x49.png\" alt=\"\" width=\"630\" height=\"103\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-300x49.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-1024x167.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-768x125.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-1536x250.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-20x3.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM-1320x215.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-5.06.26-AM.png 1734w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>An additional manifestation of the Halloween problems.<\/p>\n<p><strong>INSERT INTO t SELECT * FROM t WHERE balance &gt; 0;<\/strong><\/p>\n<h5><strong>Solution:<\/strong><\/h5>\n<p>In traditional RDBMS (e.g. Informix), the solution is fairly straight forward.\u00a0 For each of the DML statements resulting in mutation, it keeps a sorted list of rowids updated within this statement.\u00a0 Before we update a row, we check to see if this row is already updated and skip it.\u00a0 For simple updates with limited range scans, this read overhead is hardly noticeable. For larger updates, the maintenance of a large list in memory can be an issue.\u00a0 Typically, the list is spilled out to disk once it gets sufficiently large.<\/p>\n<h5><strong>Couchbase N1QL &amp; GSI solution:\u00a0<\/strong><\/h5>\n<p><span class=\"s1\">Couchbase is a distributed database with multiple services.<span class=\"Apple-converted-space\">\u00a0 The query service<\/span>\u00a0creates the e<\/span><span class=\"s1\">xecution plan and executes it.\u00a0 Here&#8217;s the overview of the solution.<\/span><\/p>\n<p><span class=\"s1\">Let&#8217;s look at the query when we have an index: <\/span><span class=\"s1\">CREATE INDEX i1 ON t<\/span><span class=\"s2\">(<\/span><span class=\"s1\">salary<\/span><span class=\"s2\">)<\/span><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9623\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM-300x170.png\" alt=\"\" width=\"584\" height=\"331\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM-300x170.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM-1024x579.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM-768x434.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM-20x11.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-6.46.15-AM.png 1220w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/a>N1QL will create a plan like this: UPDATE statement, the plan will use the index scan to identify the documents to update, fetch the document, update it and write it back.\u00a0 It&#8217;s important to note that this update is done to documents synchronously.\u00a0 These changes will flow through DCP and index updates happen asynchronously.\u00a0 Even then, for larger updates, the scan of the index and updates can be going on while the updates are done to the index being scanned.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-9624\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM-209x300.png\" alt=\"\" width=\"209\" height=\"300\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM-209x300.png 209w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM-300x431.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM-14x20.png 14w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-8.27.01-AM.png 672w\" sizes=\"auto, (max-width: 209px) 100vw, 209px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Now, let&#8217;s look at the index scan itself.\u00a0 Indexes can be built on Memory-Optimized Index (MOI) or Standard Secondary (using Plasma Storage Engine). Both of these have the concept of snapshot. Instead of updating the values in-place, we use MVCC to provide the required functionality and performance.<\/p>\n<p>Here are a couple of things from the <a href=\"https:\/\/www.vldb.org\/pvldb\/vol9\/p1413-lakshman.pdf\">Nitro<\/a> paper.<\/p>\n<p><em><strong>Immutable snapshots:<\/strong> Concurrent writers add or remove items into the skiplist. A snapshot of the current items can be created to provide a point-in-time view of the skiplist. This is useful for providing repeatable stable scans. Users can create and manage multiple snapshots. If an application requires atomicity for a batch of skiplist operations, it can apply a batch of operations and create a new snapshot. Changes would be invisible until a new snapshot is created. <\/em><\/p>\n<p><em><strong>Fast and low overhead snapshots:<\/strong> Readers of the skiplist use a snapshot handle to perform all lookup and range queries. An indexer application typically requires many snapshots to be created every second for servicing index queries. So the overhead of creating and maintaining a snapshot should be minimal for servicing the high rate of snapshot generation. Nitro snapshots are very cheap and is an O(1) operation.\u00a0<\/em><\/p>\n<p>To implement these, the index uses two things: BornSnapshot version and DeadSnapshot version. Let&#8217;s look at the state of the initial index.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM.png\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9625\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-300x46.png\" alt=\"\" width=\"665\" height=\"102\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-300x46.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-1024x157.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-768x117.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-1536x235.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-20x3.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM-1320x202.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-9.51.55-AM.png 1832w\" sizes=\"auto, (max-width: 665px) 100vw, 665px\" \/><\/a>As the changes, change in the values simply add new nodes in the skiplist with updated values, bornSnapshot and deadSnapshot values.<a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9626\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-300x68.png\" alt=\"\" width=\"719\" height=\"163\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-300x68.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-1024x231.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-768x173.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-1536x347.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-20x5.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM-1320x298.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-12.38.02-PM.png 1896w\" sizes=\"auto, (max-width: 719px) 100vw, 719px\" \/><\/a><\/p>\n<p>Using the bornSnapshot and deadSnapshot versions on the entries, index scanner (aka iterator) simply chooses the right entries to qualify index entries to read.\u00a0 That&#8217;s how it creates a snapshot and will not read the previously updated value in the same scan.\u00a0 This not only provides stable scans, but it also avoids the Halloween problem altogether! This also eliminates the need for updated-documentid list maintenance within the query service. Good engineering addressed the problem; great engineering avoids the problem altogether. :-)<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-9635\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-300x105.png\" alt=\"\" width=\"692\" height=\"242\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-300x105.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-1024x358.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-768x269.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-1536x538.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-800x280.png 800w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-20x7.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM-1320x462.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Screen-Shot-2020-11-03-at-3.10.54-PM.png 1914w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/a><\/p>\n<p>Finally, a Halloween art by <a href=\"https:\/\/twitter.com\/dhaikney\">David Haikney<\/a>, VP of Couchbase Customer Support!\u00a0<strong>Watch the full video!<\/strong><\/p>\n<blockquote class=\"twitter-tweet\">\n<p dir=\"ltr\" lang=\"en\">Happy Halloween \u2066to all \u2066<a href=\"https:\/\/twitter.com\/couchbase?ref_src=twsrc%5Etfw\">@couchbase<\/a>\u2069 ! \ud83c\udf83 <a href=\"https:\/\/t.co\/vqwW7sk3v6\">pic.twitter.com\/vqwW7sk3v6<\/a><\/p>\n<p>\u2014 David Haikney (@dhaikney) <a href=\"https:\/\/twitter.com\/dhaikney\/status\/1322594264656842752?ref_src=twsrc%5Etfw\">October 31, 2020<\/a><\/p><\/blockquote>\n<h5><\/h5>\n<h5><strong>References<\/strong><\/h5>\n<ol>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Halloween_Problem\">Halloween Problem<\/a><\/li>\n<li><a class=\"external text\" href=\"https:\/\/web.archive.org\/web\/20070718223542\/https:\/\/www.noncombatant.org\/trove\/fitzpatrick-anecdotes.pdf\" rel=\"nofollow\">A well-intentioned query and the Halloween Problem<\/a>, Los Alamos National Laboratory, Anecdotes, IEEE Annals of the History of Computing<\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/5.0\/indexes\/performance-consistency.html\">Couchbase Global Secondary Index<\/a><\/li>\n<li><a href=\"https:\/\/www.vldb.org\/pvldb\/vol9\/p1413-lakshman.pdf\">Nitro<\/a>: A Fast, Scalable In-Memory Storage Engine for NoSQL Global Secondary Index<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Learning SQL is easy; Implementing SQL, not so much. Halloween has come and gone. But, the tricks of the Halloween problem is here to stay! This has to be solved by databases every day.\u00a0 SQL made the relational database easy, [&hellip;]<\/p>\n","protected":false},"author":55,"featured_media":9603,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1821,1816,1812],"tags":[1261,1725,1385],"ppma_author":[8929],"class_list":["post-9601","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-architecture","category-couchbase-server","category-n1ql-query","tag-json","tag-nosql-database","tag-rdbms"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Halloween Problem: Solution in N1QL. - 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\/datatabase-query-halloween-problem-n1ql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Halloween Problem: Solution in N1QL.\" \/>\n<meta property=\"og:description\" content=\"Learning SQL is easy; Implementing SQL, not so much. Halloween has come and gone. But, the tricks of the Halloween problem is here to stay! This has to be solved by databases every day.\u00a0 SQL made the relational database easy, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-11-04T01:55:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T01:43:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Halloween-Problem-Solution-in-N1QL..png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"627\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\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\/datatabase-query-halloween-problem-n1ql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\"},\"author\":{\"name\":\"Keshav Murthy\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\"},\"headline\":\"Halloween Problem: Solution in N1QL.\",\"datePublished\":\"2020-11-04T01:55:44+00:00\",\"dateModified\":\"2025-06-14T01:43:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\"},\"wordCount\":990,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg\",\"keywords\":[\"JSON\",\"NoSQL Database\",\"RDBMS\"],\"articleSection\":[\"Couchbase Architecture\",\"Couchbase Server\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\",\"name\":\"Halloween Problem: Solution in N1QL. - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg\",\"datePublished\":\"2020-11-04T01:55:44+00:00\",\"dateModified\":\"2025-06-14T01:43:59+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg\",\"width\":2560,\"height\":912},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Halloween Problem: Solution in N1QL.\"}]},{\"@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":"Halloween Problem: Solution in N1QL. - 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\/datatabase-query-halloween-problem-n1ql\/","og_locale":"en_US","og_type":"article","og_title":"Halloween Problem: Solution in N1QL.","og_description":"Learning SQL is easy; Implementing SQL, not so much. Halloween has come and gone. But, the tricks of the Halloween problem is here to stay! This has to be solved by databases every day.\u00a0 SQL made the relational database easy, [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/","og_site_name":"The Couchbase Blog","article_published_time":"2020-11-04T01:55:44+00:00","article_modified_time":"2025-06-14T01:43:59+00:00","og_image":[{"width":1200,"height":627,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/Halloween-Problem-Solution-in-N1QL..png","type":"image\/png"}],"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\/datatabase-query-halloween-problem-n1ql\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/"},"author":{"name":"Keshav Murthy","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636"},"headline":"Halloween Problem: Solution in N1QL.","datePublished":"2020-11-04T01:55:44+00:00","dateModified":"2025-06-14T01:43:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/"},"wordCount":990,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg","keywords":["JSON","NoSQL Database","RDBMS"],"articleSection":["Couchbase Architecture","Couchbase Server","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/","url":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/","name":"Halloween Problem: Solution in N1QL. - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg","datePublished":"2020-11-04T01:55:44+00:00","dateModified":"2025-06-14T01:43:59+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/11\/h2-scaled.jpg","width":2560,"height":912},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/datatabase-query-halloween-problem-n1ql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Halloween Problem: Solution in N1QL."}]},{"@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\/9601","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=9601"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/9601\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/9603"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=9601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=9601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=9601"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=9601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}