{"id":10195,"date":"2021-06-09T04:05:56","date_gmt":"2021-06-09T11:05:56","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=10195"},"modified":"2025-06-13T22:39:24","modified_gmt":"2025-06-14T05:39:24","slug":"eventing-introducing-advanced-bucket-accessors-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/","title":{"rendered":"Eventing: Introducing Advanced Bucket Accessors in Couchbase"},"content":{"rendered":"<p>Advanced Bucket Accessors in Couchbase make it possible to access advanced key-value store (KV) functionality using the following built-in operators.<\/p>\n<p>They utilize the same bucket bindings defined in the handler as Basic Bucket Accessors, but expose a richer set of options and operators that can be used to:<\/p>\n<ol>\n<li>Set or retrieve expirations<\/li>\n<li>Solve race conditions via CAS<\/li>\n<li>Manipulate hot KV items under high contention<\/li>\n<\/ol>\n<p>Note that <a href=\"https:\/\/docs.couchbase.com\/server\/6.6\/eventing\/eventing-language-constructs.html?ref=blog#bucket_accessors\" target=\"_blank\" rel=\"noopener noreferrer\">Basic Bucket Accessors<\/a> are much easier to use, have a trivial API, and are also a bit faster than the corresponding Advanced Bucket Accessors.<\/p>\n<p>In Couchbase Server 6.6.1 the following Advanced Bucket Accessors have been added:<\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li><a href=\"#advanced-get-op\">Advanced GET operation<\/a><\/li>\n<li><a href=\"#advanced-insert-op\">Advanced INSERT operation<\/a><\/li>\n<li><a href=\"#advanced-upsert-op\">Advanced UPSERT operation<\/a><\/li>\n<li><a href=\"#advanced-replace-op\">Advanced REPLACE operation<\/a><\/li>\n<li><a href=\"#advanced-delete-op\">Advanced DELETE operation<\/a><\/li>\n<li><a href=\"#advanced-increment-op\">Advanced INCREMENT operation<\/a><\/li>\n<li><a href=\"#advanced-decrement-op\">Advanced DECREMENT operation<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>These seven new Bucket Accessors make it possible to utilize and leverage CAS directly to handle contention and\/or set a document expiration (or <a href=\"https:\/\/www.couchbase.com\/blog\/how-to-manage-ttl-with-couchbase-n1ql\/\">TTL<\/a>) in the Data Service (or KV) via <a href=\"https:\/\/www.couchbase.com\/products\/eventing\">Eventing<\/a> plus perform distributed atomic counter operations.<\/p>\n<p>For example, rather than blindly relying on Basic Bucket Accessors for an upsert like operation <code>src_bkt[id_str] = some_doc<\/code>, the Advanced Accessors allow you to resolve contention (or possible contention) on keys that have concurrent mutations form different sources with JavaScript-driven logic in your Eventing Function.<\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li>If the document doesn&#8217;t exist you can use <code>couchbase.insert(src_bkt, {\"id: id_str}, some_doc)<\/code> and check the return value for success<\/li>\n<li>If the document exists you can use <code>couchbase.replace(src_bkt, {\"id: id_str, \"cas\": current_cas}, some_doc)<\/code> and check the return value for success or a CAS mismatch.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>To view complete examples including JavaScript, input mutations, output mutations and\/or log messages for each Advanced Bucket Accessor, refer to <a href=\"https:\/\/docs.couchbase.com\/server\/6.6\/eventing\/eventing-examples.html?ref=blog#examples-scriptlets-advanced-accessors\" target=\"_blank\" rel=\"noopener noreferrer\">Scriptlets: Advanced Accessor Handlers<\/a> in the examples section of the documentation.<\/p>\n<p><strong id=\"advanced-get-op\">Advanced GET:<\/strong> result = <code>couchbase.get(binding, meta)<\/code><\/p>\n<p>This operation allows reading a document along with metadata from the bucket and subsequent operations to utilize CAS or check\/modify the <code>expiry_date<\/code>.<\/p>\n<p>Contrast this to the Basic Bucket Accessor <code>GET<\/code> operation which merely exposes a JavaScript binding or map, <code>var adoc = src_bkt[meta.id]<\/code>, where the return value is just the document without any metadata.<\/p>\n<p>Below is an example of the Advanced <code>GET<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input doc ', doc);\r\n    log('input meta', meta);\r\n    \/\/ could be the same or different\r\n    var new_meta = {\"id\":\"test_adv_get::1\"};\r\n    var result = couchbase.get(src_bkt,new_meta);\r\n    if (result.success) {\r\n        log('success adv. get: result',result);\r\n    } else {\r\n        log('failure adv. get: id',new_meta.id,'result',result);\r\n    }\r\n}<\/pre>\n<p>Some example return values:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"doc\": {\r\n        \"id\": 1,\r\n        \"type\": \"test_adv_get\"\r\n    },\r\n    \"meta\": {\r\n        \"id\": \"test_adv_get::1\",\r\n        \"cas\": \"1610034762747412480\",\r\n        \"data_type\": \"json\"\r\n    },\r\n    \"success\": true\r\n}\r\n\r\n{\r\n    \"doc\": {\r\n        \"a\": 1,\r\n        \"random\": 0.09799092443129842\r\n    },\r\n    \"meta\": {\r\n        \"id\": \"test_adv_insert:1\",\r\n        \"cas\": \"1610140272584884224\",\r\n        \"expiry_date\": \"2021-01-08T21:12:12.000Z\",\r\n        \"data_type\": \"json\"\r\n    },\r\n    \"success\": true\r\n}\r\n\r\n{\r\n    \"error\": {\r\n        \"code\": 272,\r\n        \"name\": \"LCB_KEY_ENOENT\",\r\n        \"desc\": \"The document key does not exist on the server\",\r\n        \"key_not_found\": true\r\n    },\r\n    \"success\": false\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-insert-op\">Advanced INSERT<\/strong>: result = <code>couchbase.insert(binding, meta, doc)<\/code><\/p>\n<p>This operation allows creating a fresh document in the bucket. This operation will fail if the document with the specified key already exists. It allows specifying an expiration time (or TTL) to be set on the document.<\/p>\n<p>There is no analogous Basic Bucket Accessor operation to the Advanced <code>INSERT<\/code> operation (as <code>src_bkt[meta.id] = adoc<\/code> is more like an upsert).<\/p>\n<p>Below is an example of the Advanced <code>INSERT<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n    \/\/ could be the same or different\r\n    var new_meta = {\"id\":\"test_adv_insert:1\"};\r\n    \/\/ optional set an expiry 60 seconds in the future\r\n    \/\/ new_meta.expiry_date = new Date(Date.now() + 60 * 1000);\r\n    var new_doc = doc;\r\n    new_doc.random = Math.random();\r\n    var result = couchbase.insert(src_bkt,new_meta,new_doc);\r\n    if (result.success) {\r\n        log('success adv. insert: result',result);\r\n    } else {\r\n        log('failure adv. insert: id',new_meta.id,'result',result);\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Some example return values:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"meta\": {\r\n        \"id\": \"test_adv_insert:1\",\r\n        \"cas\": \"1610041053310025728\"\r\n    },\r\n    \"success\": true\r\n}\r\n\r\n{\r\n    \"error\": {\r\n        \"code\": 272,\r\n        \"name\": \"LCB_KEY_EEXISTS\",\r\n        \"desc\": \"The document key already exists in the server.\",\r\n        \"key_already_exists\": true\r\n    },\r\n    \"success\": false\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-upsert-op\">Advanced UPSERT<\/strong>: result = <code>couchbase.upsert(binding, meta, doc)<\/code><\/p>\n<p>This operation allows updating an existing document in the bucket, or if absent, creating a fresh document with the specified key. The operation does not allow specifying CAS (it will be silently ignored). It also allows specifying an expiration time (or TTL) to be set on the document.<\/p>\n<p>Contrast this to the Basic Bucket Accessor <code>SET<\/code> operation which merely uses an exposed JavaScript map defined via a bucket binding alias <code>src_bkt[meta.id] = adoc<\/code>. For the basic <code>SET<\/code> operation there is no return value (no status and no metadata) thus no way to check the CAS value.<\/p>\n<p>Below is an example of the Advanced <code>UPSERT<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n    \/\/ could be the same or different\r\n    var new_meta = {\"id\":\"test_adv_upsert:1\"}; \/\/ CAS if supplied will be ignored\r\n    \/\/ optional set an expiry 60 seconds in the future\r\n    \/\/ new_meta.expiry_date = new Date(Date.now() + 60 * 1000);\r\n    var new_doc = doc;\r\n    new_doc.random = Math.random();\r\n    var result = couchbase.upsert(src_bkt,new_meta,new_doc);\r\n    if (result.success) {\r\n        log('success adv. upsert: result',result);\r\n    } else {\r\n        log('failure adv. upsert: id',new_meta.id,'result',result);\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>An example return value:<\/p>\n<pre class=\"lang:js decode:true \">{\r\n    \"meta\": {\r\n        \"id\": \"test_adv_upsert:1\",\r\n        \"cas\": \"1610127444908376064\"\r\n    },\r\n    \"success\": true\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-replace-op\">Advanced REPLACE<\/strong>: result = <code>couchbase.replace(binding, meta, doc)<\/code><\/p>\n<p>This operation replaces an existing document in the bucket. This operation will fail if the document with the specified key does not exist. This operation allows specifying a CAS value that must be matched as a pre-condition before proceeding with the operation. It also allows specifying an expiration time (or TTL) to be set on the document.<\/p>\n<p>There is no analogous Basic Bucket Accessor operation to the Advanced <code>REPLACE<\/code> operation (as <code>src_bkt[meta.id] = adoc<\/code> is more like an upsert).<\/p>\n<p>Below is an example of the Advanced <code>REPLACE<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n\r\n    var mode = 3; \/\/ 1-&gt; no CA, 2-&gt; mismatch in CA, 3-&gt; good CAS\r\n\r\n    \/\/ Setup, make sure we have our doc to \"replace\", ignore any errors\r\n    couchbase.insert(src_bkt,{\"id\":\"test_adv_replace:10\"},{\"a:\": 1});\r\n\r\n    var new_meta;\r\n    if (mode === 1) {\r\n        \/\/ If we pass no CAS it will succeed\r\n        new_meta = {\"id\":\"test_adv_replace:10\"};\r\n        \/\/ optional set an expiry 60 seconds in the future\r\n        \/\/ new_meta.expiry_date = new Date(Date.now() + 60 * 1000);\r\n    }\r\n    if (mode === 2) {\r\n        \/\/ If we pass a non-matching CAS it will fail, so test this\r\n        new_meta = {\"id\":\"test_adv_replace:10\", \"cas\":\"1111111111111111111\"};\r\n    }\r\n    if (mode === 3) {\r\n        \/\/ If we pass the matching or current CAS it will succeed\r\n        var tmp_r = couchbase.get(src_bkt,{\"id\":\"test_adv_replace:10\"});\r\n        if (tmp_r.success) {\r\n            \/\/ Here we use the current CAS just read via couchbase.get(...)\r\n            new_meta = {\"id\":\"test_adv_replace:10\", \"cas\": tmp_r.meta.cas};\r\n        } else {\r\n            log('Cannot replace non-existing key that create it and rerun',\"test_adv_replace:10\");\r\n            return;\r\n        }\r\n    }\r\n    var new_doc = doc;\r\n    new_doc.random = Math.random();\r\n    var result = couchbase.replace(src_bkt,new_meta,new_doc);\r\n    if (result.success) {\r\n        log('success adv. replace: result',result);\r\n    } else {\r\n        log('failure adv. replace: id',new_meta.id,'result',result);\r\n    }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Some example return values:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"meta\": {\r\n        \"id\": \"test_adv_replace:10\",\r\n        \"cas\": \"1610130177286144000\"\r\n    },\r\n    \"success\": true\r\n}\r\n\r\n{\r\n    \"error\": {\r\n        \"code\": 272,\r\n        \"name\": \"LCB_KEY_EEXISTS\",\r\n        \"desc\": \"The document key exists with a CAS value different than specified\",\r\n        \"cas_mismatch\": true\r\n    },\r\n    \"success\": false\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-delete-op\">Advanced DELETE<\/strong>: result = <code>couchbase.delete(binding, meta)<\/code><\/p>\n<p>This operation allows deleting a document in the bucket specified by key. Optionally, a CAS value may be specified which will be matched as a pre-condition to proceed with the operation.<\/p>\n<p>Contrast this to the Basic Bucket Accessor <code>DEL<\/code> operation which merely uses an exposed a JavaScript binding or map, <code>delete src_bkt[meta.id]<\/code>, where there is no return value (no status and no metadata).<\/p>\n<p>Below is an example of the Advanced <code>DELETE<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n\r\n    var mode = 4; \/\/ 1-&gt; no CA, 2-&gt; mismatch in CA, 3-&gt; good CAS, 4-&gt; no such key\r\n\r\n    \/\/ Setup, make sure we have our doc to \"delete\", ignore any errors\r\n    couchbase.insert(src_bkt,{\"id\":\"test_adv_delete:10\"},{\"a:\": 1});\r\n\r\n    var new_meta;\r\n    if (mode === 1) {\r\n        \/\/ If we pass no CAS it will succeed\r\n        new_meta = {\"id\":\"test_adv_delete:10\"};\r\n        \/\/ optional set an expiry 60 seconds in the future\r\n        \/\/ new_meta.expiry_date = new Date(Date.now() + 60 * 1000);\r\n    }\r\n    if (mode === 2) {\r\n        \/\/ If we pass a non-matching CAS it will fail, so test this\r\n        new_meta = {\"id\":\"test_adv_delete:10\", \"cas\":\"1111111111111111111\"};\r\n    }\r\n    if (mode === 3) {\r\n        \/\/ If we pass the matching or current CAS it will succeed\r\n        var tmp_r = couchbase.get(src_bkt,{\"id\":\"test_adv_delete:10\"});\r\n        if (tmp_r.success) {\r\n            \/\/ Here we use the current CAS just read via couchbase.get(...)\r\n            new_meta = {\"id\":\"test_adv_delete:10\", \"cas\": tmp_r.meta.cas};\r\n        } else {\r\n            log('Cannot delete non-existing key that create it and rerun',\"test_adv_delete:10\");\r\n            return;\r\n        }\r\n    }\r\n    if (mode === 4) {\r\n        \/\/ Remove so that we have: no such key\r\n        delete src_bkt[\"test_adv_delete:10\"]\r\n        new_meta = {\"id\":\"test_adv_delete:10\"};\r\n    }\r\n    var result = couchbase.delete(src_bkt,new_meta);\r\n    if (result.success) {\r\n        log('success adv. delete: result',result);\r\n    } else {\r\n        log('failure adv. delete: id',new_meta.id,'result',result);\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Some example return values:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"meta\": {\r\n        \"id\": \"key::10\",\r\n        \"cas\": \"1609374065129816064\"\r\n    },\r\n    \"success\": true\r\n}\r\n\r\n{\r\n    \"error\": {\r\n        \"code\": 272,\r\n        \"name\": \"LCB_KEY_EEXISTS\",\r\n        \"desc\": \"The document key exists with a CAS value different than specified\",\r\n        \"cas_mismatch\": true\r\n    },\r\n    \"success\": false\r\n}\r\n\r\n{\r\n    \"error\": {\r\n        \"code\": 272,\r\n        \"name\": \"LCB_KEY_ENOENT\",\r\n        \"desc\": \"The document key does not exist on the server\",\r\n        \"key_not_found\": true\r\n    },\r\n    \"success\": false\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-increment-op\">Advanced INCREMENT<\/strong>: result = <code>couchbase.increment(binding, meta)<\/code><\/p>\n<p>This operation atomically increments the field <code>count<\/code> in the specified document. The document must have the below structure:<\/p>\n<pre class=\"lang:js decode:true \">{\"count\": 23} \/\/ 23 is the current counter value\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>The <code>increment<\/code> operation returns the post-increment value.<\/p>\n<p>If the specified counter document does not exist, one is created with <code>count<\/code> value as 0 and the structure noted above. And so, the first returned value will be 1.<\/p>\n<p>Due to limitations in KV engine API, this operation cannot currently manipulate full document counters.<\/p>\n<p>There is no analogous Basic Bucket Accessor operation to the Advanced <code>INCREMENT<\/code> operation.<\/p>\n<p>Below is an example of the Advanced <code>INCREMENT<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n\r\n    \/\/ if doc.count doesn't exist it will be created\r\n    var ctr_meta = {\"id\": \"my_atomic_counter:1\" };\r\n    var result = couchbase.increment(src_bkt,ctr_meta);\r\n    if (result.success) {\r\n        log('success adv. increment: result',result);\r\n    } else {\r\n        log('failure adv. increment: id',ctr_meta.id,'result',result);\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>An example return value, assume you create this <code>KEY \"my_atomic_counter:1\" DOC {\"count\": 23}<\/code> if the Eventing function above is deployed the count will be immediately incremented:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"doc\": {\r\n        \"count\": 24\r\n    },\r\n    \"meta\": {\r\n        \"id\": \"key::1\",\r\n        \"cas\": \"1609374571840471040\"\r\n    },\r\n    \"success\": true\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong id=\"advanced-decrement-op\">Advanced DECREMENT<\/strong>: result = <code>couchbase.decrement(binding, meta)<\/code><\/p>\n<p>This operation atomically decrements the field <code>count<\/code> in the specified document. The document must have the below structure:<\/p>\n<pre class=\"lang:js decode:true\">{\"count\": 23} \/\/ 23 is the current counter value\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>The <code>decrement<\/code> operation returns the post-decrement value.<\/p>\n<p>If the specified counter document does not exist, one is created with the <code>count<\/code> value as 0 and the structure noted above. As a result, the first returned value will be -1.<\/p>\n<p>Due to limitations in KV engine API, this operation cannot currently manipulate full document counters.<\/p>\n<p>There is no analogous Basic Bucket Accessor operation to the Advanced <code>DECREMENT<\/code> operation.<\/p>\n<p>Below is an example of the Advanced <code>DECREMENT<\/code> operation.<\/p>\n<pre class=\"lang:js decode:true\">function OnUpdate(doc, meta) {\r\n    log('input meta', meta);\r\n    log('input doc ', doc);\r\n\r\n    \/\/ if doc.count doesn't exist it will be created\r\n    var ctr_meta = {\"id\": \"my_atomic_counter:1\" };\r\n    var result = couchbase.decrement(src_bkt,ctr_meta);\r\n    if (result.success) {\r\n        log('success adv. decrement: result',result);\r\n    } else {\r\n        log('failure adv. decrement: id',ctr_meta.id,'result',result);\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>An example return value, assume you create this <code>KEY \"my_atomic_counter:1\" DOC {\"count\": 23}<\/code> if the Eventing function above is deployed the count will be immediately decremented:<\/p>\n<pre class=\"lang:js decode:true\">{\r\n    \"doc\": {\r\n        \"count\": 22\r\n    },\r\n    \"meta\": {\r\n        \"id\": \"key::1\",\r\n        \"cas\": \"1609374770297176064\"\r\n    },\r\n    \"success\": true\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h2>References<\/h2>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/eventing\/eventing-overview.html?ref=blog\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Eventing documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/eventing\/eventing-advanced-keyspace-accessors.html?ref=blog\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Eventing Advanced Accessors documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/current\/eventing\/eventing-examples.html?ref=blog\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Eventing examples<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/server\/6.6\/introduction\/whats-new.html?ref=blog\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Server 6.6 What&#8217;s New<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/tag\/eventing\/?ref=blog\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase blogs on Eventing<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Advanced Bucket Accessors in Couchbase make it possible to access advanced key-value store (KV) functionality using the following built-in operators. They utilize the same bucket bindings defined in the handler as Basic Bucket Accessors, but expose a richer set of [&hellip;]<\/p>\n","protected":false},"author":42711,"featured_media":10196,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,2273,9327],"tags":[1543,9247,1991],"ppma_author":[9113],"class_list":["post-10195","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-eventing","category-javascript","tag-javascript","tag-key-value-store","tag-ttl"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Eventing: Introducing Advanced Bucket Accessors in Couchbase<\/title>\n<meta name=\"description\" content=\"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.\" \/>\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\/eventing-introducing-advanced-bucket-accessors-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Eventing: Introducing Advanced Bucket Accessors in Couchbase\" \/>\n<meta property=\"og:description\" content=\"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-09T11:05:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T05:39:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jon Strabala, Principal Product Manager, 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=\"Jon Strabala, Principal Product Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\"},\"author\":{\"name\":\"Jon Strabala, Principal Product Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c991579f88217edee79ffedb6fc914cc\"},\"headline\":\"Eventing: Introducing Advanced Bucket Accessors in Couchbase\",\"datePublished\":\"2021-06-09T11:05:56+00:00\",\"dateModified\":\"2025-06-14T05:39:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\"},\"wordCount\":939,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png\",\"keywords\":[\"javascript\",\"key-value store\",\"TTL\"],\"articleSection\":[\"Couchbase Server\",\"Eventing\",\"JavaScript\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\",\"name\":\"Eventing: Introducing Advanced Bucket Accessors in Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png\",\"datePublished\":\"2021-06-09T11:05:56+00:00\",\"dateModified\":\"2025-06-14T05:39:24+00:00\",\"description\":\"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png\",\"width\":1200,\"height\":628,\"caption\":\"Learn how to use Advanced Bucket Accessors in Couchbase for key-value store Eventing\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Eventing: Introducing Advanced Bucket Accessors in Couchbase\"}]},{\"@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\/c991579f88217edee79ffedb6fc914cc\",\"name\":\"Jon Strabala, Principal Product Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9c6045b0c2f7b07b0ee10f94ad748a25\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/db52a9f6d84faba430dd38106cdbc16ff02c2066b103b5f6b4cfcde40e83c683?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/db52a9f6d84faba430dd38106cdbc16ff02c2066b103b5f6b4cfcde40e83c683?s=96&d=mm&r=g\",\"caption\":\"Jon Strabala, Principal Product Manager, Couchbase\"},\"description\":\"Jon Strabala is a Principal Product Manager, responsible for the Couchbase Eventing Service. Before joining Couchbase, he spent more than 20 years building software products across various domains, starting with EDA in aerospace then transitioning to building enterprise software focused on what today is coined \u201cIoT\u201d and \u201cat-scale data.\u201d Jon worked for several small software consultancies until eventually starting and managing his own firm. He has extensive experience in NoSQL\/NewSQL, both in contributing and commercializing new technologies such as compressed bitmaps and column stores. Jon holds a bachelor\u2019s degree in electrical engineering and a master's in computer engineering, both from the University of Southern California, and an MBA from the University of California at Irvine.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/jon-strabala\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Eventing: Introducing Advanced Bucket Accessors in Couchbase","description":"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.","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\/eventing-introducing-advanced-bucket-accessors-couchbase\/","og_locale":"en_US","og_type":"article","og_title":"Eventing: Introducing Advanced Bucket Accessors in Couchbase","og_description":"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.","og_url":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-06-09T11:05:56+00:00","article_modified_time":"2025-06-14T05:39:24+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png","type":"image\/png"}],"author":"Jon Strabala, Principal Product Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jon Strabala, Principal Product Manager, Couchbase","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/"},"author":{"name":"Jon Strabala, Principal Product Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c991579f88217edee79ffedb6fc914cc"},"headline":"Eventing: Introducing Advanced Bucket Accessors in Couchbase","datePublished":"2021-06-09T11:05:56+00:00","dateModified":"2025-06-14T05:39:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/"},"wordCount":939,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png","keywords":["javascript","key-value store","TTL"],"articleSection":["Couchbase Server","Eventing","JavaScript"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/","name":"Eventing: Introducing Advanced Bucket Accessors in Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png","datePublished":"2021-06-09T11:05:56+00:00","dateModified":"2025-06-14T05:39:24+00:00","description":"Learn how to implement Advanced Bucket Accessors in Couchbase Server for Eventing to get direct access to TTLs, CAS values and more key-value functionality.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/01\/banner.png","width":1200,"height":628,"caption":"Learn how to use Advanced Bucket Accessors in Couchbase for key-value store Eventing"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/eventing-introducing-advanced-bucket-accessors-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Eventing: Introducing Advanced Bucket Accessors in Couchbase"}]},{"@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\/c991579f88217edee79ffedb6fc914cc","name":"Jon Strabala, Principal Product Manager, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9c6045b0c2f7b07b0ee10f94ad748a25","url":"https:\/\/secure.gravatar.com\/avatar\/db52a9f6d84faba430dd38106cdbc16ff02c2066b103b5f6b4cfcde40e83c683?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/db52a9f6d84faba430dd38106cdbc16ff02c2066b103b5f6b4cfcde40e83c683?s=96&d=mm&r=g","caption":"Jon Strabala, Principal Product Manager, Couchbase"},"description":"Jon Strabala is a Principal Product Manager, responsible for the Couchbase Eventing Service. Before joining Couchbase, he spent more than 20 years building software products across various domains, starting with EDA in aerospace then transitioning to building enterprise software focused on what today is coined \u201cIoT\u201d and \u201cat-scale data.\u201d Jon worked for several small software consultancies until eventually starting and managing his own firm. He has extensive experience in NoSQL\/NewSQL, both in contributing and commercializing new technologies such as compressed bitmaps and column stores. Jon holds a bachelor\u2019s degree in electrical engineering and a master's in computer engineering, both from the University of Southern California, and an MBA from the University of California at Irvine.","url":"https:\/\/www.couchbase.com\/blog\/author\/jon-strabala\/"}]}},"authors":[{"term_id":9113,"user_id":42711,"is_guest":0,"slug":"jon-strabala","display_name":"Jon Strabala, Principal Product Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/db52a9f6d84faba430dd38106cdbc16ff02c2066b103b5f6b4cfcde40e83c683?s=96&d=mm&r=g","author_category":"","last_name":"Strabala, Principal Product Manager, Couchbase","first_name":"Jon","job_title":"","user_url":"","description":"Jon Strabala is a Principal Product Manager, responsible for the Couchbase Eventing Service. Before joining Couchbase, he spent more than 20 years building software products across various domains, starting with EDA in aerospace then transitioning to building enterprise software focused on what today is coined \u201cIoT\u201d and \u201cat-scale data.\u201d Jon worked for several small software consultancies until eventually starting and managing his own firm. He has extensive experience in NoSQL\/NewSQL, both in contributing and commercializing new technologies such as compressed bitmaps and column stores. Jon holds a bachelor\u2019s degree in electrical engineering and a master's in computer engineering, both from the University of Southern California, and an MBA from the University of California at Irvine."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/10195","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\/42711"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=10195"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/10195\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/10196"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=10195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=10195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=10195"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=10195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}