{"id":5911,"date":"2018-10-20T18:06:25","date_gmt":"2018-10-21T01:06:25","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=5911"},"modified":"2025-06-13T22:39:36","modified_gmt":"2025-06-14T05:39:36","slug":"using-n1ql-with-couchbase-eventing-functions","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/","title":{"rendered":"Using N1QL with Couchbase Eventing Functions."},"content":{"rendered":"<blockquote><p><span style=\"font-weight: 400\">Now, this is not the end. It is not even the beginning of the end. <\/span><span style=\"font-weight: 400\">But it is, perhaps, the end of the beginning. &#8212; Winston Churchill<\/span><\/p><\/blockquote>\n<p><span style=\"font-weight: 400\">Updating data is usually not the end, but usually a progress of a workflow. \u00a0Shipping follows ordering; inventory update follows shipping; adjusting credit follows returning; \u00a0The next step in the process is required to act to keep the workflow going. The workflows can be simple with few steps or complex with hundreds of steps. \u00a0<\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Business_process_management\"><span style=\"font-weight: 400\">Business Process Management<\/span><\/a><span style=\"font-weight: 400\"> (BPM) is an industry by itself.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Couchbase 5.5 introduced <a href=\"https:\/\/docs.couchbase.com\/server\/6.0\/eventing\/eventing-overview.html\">Evening service<\/a>. Developers can write a Javascript function to execute upon a change to the data. We refer inserts, Updates, Merges, and Deletions together as <\/span><i><span style=\"font-weight: 400\">mutations.<\/span><\/i><span style=\"font-weight: 400\"> Multiple specific use cases <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/5.5\/eventing\/eventing-overview.html\"><span style=\"font-weight: 400\">have been documented<\/span><\/a><span style=\"font-weight: 400\"> for developing these <a href=\"https:\/\/www.couchbase.com\/products\/eventing\/\">eventing<\/a> functions.<\/span><\/p>\n<p><a href=\"https:\/\/www.json.org\"><span style=\"font-weight: 400\">JSON<\/span><\/a><span style=\"font-weight: 400\"> data model in Couchbase came from <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/JavaScript\"><span style=\"font-weight: 400\">JavaScript<\/span><\/a><span style=\"font-weight: 400\">. \u00a0<\/span><a href=\"https:\/\/docs.couchbase.com\/server\/5.5\/n1ql\/n1ql-language-reference\/index.html\"><span style=\"font-weight: 400\">N1QL<\/span><\/a><span style=\"font-weight: 400\"> is SQL for JSON. The eventing functions are written in Javascript and has integrated N1QL. Using the Eventing functions, writing procedural business logic with instant access to data easy.<\/span><\/p>\n<pre class=\"theme:github font:consolas wrap:true whitespace-before:1 whitespace-after:1 lang:js decode:true\" title=\"Sample Eventing Function for Insert and Update\">\/\/ Simple counting function\r\n\/\/ After every update to travel sample, keep track of the total number of documents of each type.\r\nfunction OnUpdate(doc, meta) {\r\n    try {\r\n   \r\n    \/\/ Issue SELECT statement to get the counts.\r\n    var ginfo = SELECT type, COUNT(type) typecount FROM `travel-sample` WHERE `type` IS NOT MISSING GROUP BY type;\r\n\r\n    \/\/ loop through the resultset\r\n    for (var val of ginfo) {\r\n      var ckey = \"trcount\" + val.type;  \/\/ Create the document key-string.\r\n      var vtype = val.type; var vtc = val.typecount;  \/\/ get the type, count\r\n      \/\/ do the update.\r\n      UPDATE T1 USE KEYS[$ckey] SET  type =  $vtype, typecount =$vtc;\r\n    }\r\n  } catch(e) { log(e); }    \r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400\">Here\u2019s the lifecycle of the functions from a developer perspective. For every mutation, you can define any number of these functions to be executed. It\u2019s the developer responsibility to size the execution times of the functions, depending on the number of mutations.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Here\u2019s the lifecycle of the Eventing functions:<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/10\/lifecycle-overview-5.5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-8363\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/10\/lifecycle-overview-5.5-300x150.png\" alt=\"\" width=\"855\" height=\"428\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5-300x150.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5-1024x511.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5-768x383.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5-20x10.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5-1320x659.png 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png 1394w\" sizes=\"auto, (max-width: 855px) 100vw, 855px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400\">For every insert, update or delete (direct or expiry), you can execute one or more javascript functions. \u00a0These functions can read the new data and type of action and then execute the subsequent action. This functionality is well described in Couchbase blogs, and articles.<\/span><\/p>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<td><span style=\"font-weight: 400\">Statement Type<\/span><\/td>\n<td><span style=\"font-weight: 400\">Eventing Function Invoked<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT<\/span><\/td>\n<td><span style=\"font-weight: 400\">None<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">INSERT <\/span><\/td>\n<td><span style=\"font-weight: 400\">OnUpdate(). \u00a0The function is invoked <\/span><b>once per document inserted. <\/b><span style=\"font-weight: 400\">Simple insert inserts a single document. Inserts can have multiple documents using multiple documents in the VALUES clause or can insert multiple documents via INSERT INTO&#8230;SELECT statement.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">UPDATE<\/span><\/td>\n<td><span style=\"font-weight: 400\">OnUpdate() is invoked <\/span><b>once per document updated, except when multiple updates on the same document is deduped into a single update. <\/b><span style=\"font-weight: 400\">Update statement can update multiple documents.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">UPSERT<\/span><\/td>\n<td><span style=\"font-weight: 400\">OnUpdate(). \u00a0The behavior is similar to INSERT.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">DELETE<\/span><\/td>\n<td><span style=\"font-weight: 400\">OnDelete(). Invoked once per documented deleted.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">MERGE<\/span><\/td>\n<td><span style=\"font-weight: 400\">OnUpdate() and\/or OnDelete() depending on the insert, update, and delete actions. <\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">CREATE INDEX, DROP INDEX, EXPLAIN, PREPARE, GRANT, REVOKE<\/span><\/td>\n<td><span style=\"font-weight: 400\">No eventing function is invoked.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">EXECUTE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Depends on the type of the statement executed.<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><span style=\"font-weight: 400\">These functions can also execute N1QL statements. \u00a0Rest of the article looks at all aspects of N1QL executed in Eventing Functions.<\/span><\/p>\n<p><b>N1QL Statements in Eventing functions.<\/b><\/p>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<td><span style=\"font-weight: 400\">Statement<\/span><\/td>\n<td><span style=\"font-weight: 400\">Use cases for N1QL statements in Eventing Functions<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">CREATE INDEX<\/span><\/td>\n<td><span style=\"font-weight: 400\">Since the schema is flexible, you could potentially inspect the data often\/periodically to detect new fields and then create indexes on it.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">DELETE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Cascade deletes.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">DROP INDEX<\/span><\/td>\n<td><span style=\"font-weight: 400\">A corollary to the CREATE INDEX use case.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">INFER<\/span><\/td>\n<td><span style=\"font-weight: 400\">Periodic introspection of the bucket for the structure. \u00a0Then take action (validate, create index, update the data model) if necessary.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">INSERT<\/span><\/td>\n<td><span style=\"font-weight: 400\">Maintaining referential data (eventually).<\/span><\/p>\n<p><span style=\"font-weight: 400\">Updating other documents with references to this data. \u00a0E.g Data from a new zip, state, etc.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Data copy (fully or partially) to secondary\/tertiary documents. Similar to post-trigger action.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">MERGE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Keep the secondary data in sync.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">SELECT<\/span><\/td>\n<td><span style=\"font-weight: 400\">Fetch any data, run any reports periodically, etc.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Check for various things like data quality, data validity, <\/span><\/p>\n<p><span style=\"font-weight: 400\">When you do know the target document key, use the built-in direct document references. See examples at: <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/5.5\/eventing\/eventing-examples.html\"><span style=\"font-weight: 400\">https:\/\/docs.couchbase.com\/server\/5.5\/eventing\/eventing-examples.html<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">UPSERT<\/span><\/td>\n<td><span style=\"font-weight: 400\">Keeping secondary\/tertiary data in sync.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Similar to post-trigger action.<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400\">UPDATE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Keeping secondary\/tertiary data in sync.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Similar to post-trigger action.<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Examples:\u00a0 Let&#8217;s try some eventing functions with N1QL.<\/p>\n<pre class=\"theme:github wrap:true scroll:true whitespace-before:1 whitespace-after:1 lang:js decode:true\" title=\"Initial Data\">select meta().id, * from execute S1;\r\n\r\n[\r\n  {\r\n    \"S1\": {\r\n      \"name\": \"Joe Smith\",\r\n      \"zip\": \"94501\"\r\n    },\r\n    \"id\": \"Joe::94040\"\r\n  },\r\n  {\r\n    \"S1\": {\r\n      \"name\": \"John Smith\",\r\n      \"zip\": \"94040\"\r\n    },\r\n    \"id\": \"John::94040\"\r\n  }\r\n]\r\n\r\n\r\n\r\nselect meta().id, * from S2;\r\n\r\n\r\n[\r\n  {\r\n    \"S2\": {\r\n      \"name\": \"Joe Smith\",\r\n      \"zip\": \"94501\"\r\n    },\r\n    \"id\": \"Joe::94040\"\r\n  },\r\n  {\r\n    \"S2\": {\r\n      \"name\": \"John Smith\",\r\n      \"zip\": \"94040\"\r\n    },\r\n    \"id\": \"John::94040\"\r\n  }\r\n]\r\n\r\n\r\nselect meta().id, * from T1;\r\n&lt;No data&gt;\r\n<\/pre>\n<ol>\n<li><b>Simple N1QL in Functions for logging and cascade delete.<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Save away every deleted document in a separate bucket.<\/span><\/p>\n<pre class=\"theme:github lang:js decode:true \" title=\"Complete example.\">function OnUpdate(doc, meta) {\r\n}\r\nfunction OnDelete(meta) {\r\n  try {\r\n      var myid = meta.id;\r\n      \/\/Insert into the bucket of \r\n      INSERT INTO T1 VALUES(UUID(), {\"type\" : \"deleted\", \"docid\":$myid});\r\n      \/\/Cascade delete\r\n      DELETE FROM S2 USE KEYS [$myid];\r\n  } catch(e) { log(e); }\r\n}\r\n\r\nAfter creating the function above, the application Runs the following:\r\n\r\nDELETE FROM S1 WHERE zip = \"94040\";\r\n\/\/ One document was deleted.\r\n\r\nSELECT meta().id, * from S1;\r\n\/\/ one document just got deleted. There should be only one document remaining.\r\n[\r\n  {\r\n    \"S1\": {\r\n      \"name\": \"Joe Smith\",\r\n      \"zip\": \"94501\"\r\n    },\r\n    \"id\": \"Joe::94040\"\r\n  }\r\n]\r\n\r\n\r\n\r\nSELECT meta().id, * from T1;\r\n\/\/ We should see a log of the deleted\r\n[\r\n  {\r\n    \"T1\": {\r\n      \"docid\": \"John::94040\",\r\n      \"type\": \"deleted\"\r\n    },\r\n    \"id\": \"2dc9b33d-3cd4-422e-af9c-b0c664c4660f\"\r\n  }\r\n]\r\n\r\nSELECT meta().id, * FROM S2;\r\n\/\/ We should only see one document due to the effect of cascade delete from the the function\r\n[\r\n  {\r\n    \"S2\": {\r\n      \"name\": \"Joe Smith\",\r\n      \"zip\": \"94501\"\r\n    },\r\n    \"id\": \"Joe::94040\"\r\n  }\r\n]\r\n<\/pre>\n<ol start=\"2\">\n<li><b>OnUpdate() function to keep the aggregate information ready periodically.<\/b><\/li>\n<\/ol>\n<pre class=\"theme:github wrap:true whitespace-before:1 whitespace-after:1 lang:js decode:true \" title=\"Periodic reporting\">function OnUpdate(doc, meta) {\r\n    try {\r\n        var stattime = SELECT lastupdate FROM T1 USE KEYS [\"trstattime\"];\r\n        for (var t of stattime) {\r\n            var lt = t.lastupdate;\r\n            var d = new Date();\r\n            var n = d.getTime();\r\n            \/\/ Every 10 minutes or more\r\n            if ((n - lt)  &gt; (1000 * 60 * 10)) {  \r\n                UPDATE  T1 USE KEYS[\"trstattime\"]  SET lastupdate = NOW_MILLIS() ;\r\n                var ginfo = SELECT type, count(type) typecount FROM `travel-sample` WHERE `type` IS NOT MISSING GROUP BY type;\r\n                for (var val of ginfo) {\r\n                   var ckey = \"trcount::\" + val.type;\r\n                   var vtype = val.type; var vtc = val.typecount;\r\n                   UPDATE T1 USE KEYS[$ckey] SET  type =  $vtype, typecount = $vtc;\r\n                }\r\n        }\r\n     }\r\n    } catch(e) { log(e); }    \r\n}\r\n\r\n<\/pre>\n<p><strong>References:<\/strong><\/p>\n<ol>\n<li>Couchbase documentation:\u00a0<a href=\"https:\/\/docs.couchbase.com\/server\/5.5\/eventing\/eventing-overview.html\">https:\/\/docs.couchbase.com\/server\/5.5\/eventing\/eventing-overview.html<\/a><\/li>\n<li>Couchbase blogs on eventing:\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/tag\/eventing\/\">https:\/\/www.couchbase.com\/blog\/tag\/eventing\/<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Now, this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning. &#8212; Winston Churchill Updating data is usually not the end, but usually a progress of a [&hellip;]<\/p>\n","protected":false},"author":55,"featured_media":8363,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1821,1816,2273,1812],"tags":[2134,2133,2290],"ppma_author":[8929],"class_list":["post-5911","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-architecture","category-couchbase-server","category-eventing","category-n1ql-query","tag-actions","tag-functions","tag-workflow"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using N1QL with Couchbase Eventing Functions. - 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\/using-n1ql-with-couchbase-eventing-functions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using N1QL with Couchbase Eventing Functions.\" \/>\n<meta property=\"og:description\" content=\"Now, this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning. &#8212; Winston Churchill Updating data is usually not the end, but usually a progress of a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-10-21T01:06:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T05:39:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1394\" \/>\n\t<meta property=\"og:image:height\" content=\"696\" \/>\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=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\"},\"author\":{\"name\":\"Keshav Murthy\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636\"},\"headline\":\"Using N1QL with Couchbase Eventing Functions.\",\"datePublished\":\"2018-10-21T01:06:25+00:00\",\"dateModified\":\"2025-06-14T05:39:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\"},\"wordCount\":662,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png\",\"keywords\":[\"actions\",\"functions\",\"workflow\"],\"articleSection\":[\"Couchbase Architecture\",\"Couchbase Server\",\"Eventing\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\",\"name\":\"Using N1QL with Couchbase Eventing Functions. - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png\",\"datePublished\":\"2018-10-21T01:06:25+00:00\",\"dateModified\":\"2025-06-14T05:39:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png\",\"width\":1394,\"height\":696,\"caption\":\"Eventing Life Cycle 5.5\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using N1QL with Couchbase Eventing Functions.\"}]},{\"@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":"Using N1QL with Couchbase Eventing Functions. - 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\/using-n1ql-with-couchbase-eventing-functions\/","og_locale":"en_US","og_type":"article","og_title":"Using N1QL with Couchbase Eventing Functions.","og_description":"Now, this is not the end. It is not even the beginning of the end. But it is, perhaps, the end of the beginning. &#8212; Winston Churchill Updating data is usually not the end, but usually a progress of a [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-10-21T01:06:25+00:00","article_modified_time":"2025-06-14T05:39:36+00:00","og_image":[{"width":1394,"height":696,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png","type":"image\/png"}],"author":"Keshav Murthy","twitter_card":"summary_large_image","twitter_creator":"@rkeshavmurthy","twitter_misc":{"Written by":"Keshav Murthy","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/"},"author":{"name":"Keshav Murthy","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c261644262bf98e146372fe647682636"},"headline":"Using N1QL with Couchbase Eventing Functions.","datePublished":"2018-10-21T01:06:25+00:00","dateModified":"2025-06-14T05:39:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/"},"wordCount":662,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png","keywords":["actions","functions","workflow"],"articleSection":["Couchbase Architecture","Couchbase Server","Eventing","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/","url":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/","name":"Using N1QL with Couchbase Eventing Functions. - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png","datePublished":"2018-10-21T01:06:25+00:00","dateModified":"2025-06-14T05:39:36+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/10\/lifecycle-overview-5.5.png","width":1394,"height":696,"caption":"Eventing Life Cycle 5.5"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/using-n1ql-with-couchbase-eventing-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using N1QL with Couchbase Eventing Functions."}]},{"@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\/5911","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=5911"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/5911\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/8363"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=5911"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=5911"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=5911"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=5911"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}