{"id":13854,"date":"2022-11-03T13:43:33","date_gmt":"2022-11-03T20:43:33","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=13854"},"modified":"2024-09-12T01:42:30","modified_gmt":"2024-09-12T08:42:30","slug":"from-n1ql-to-javascript-and-back-part-7","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/","title":{"rendered":"From N1QL to JavaScript and Back &#8211; Part 7: Hierarchical JavaScript Storage"},"content":{"rendered":"<p><span style=\"font-weight: 400\">In previous blogs, we covered executing N1QL (SQL++) from JavaScript\u00a0<a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-1-introduction\/\" target=\"_blank\" rel=\"noopener\">functions<\/a>, processing documents\u00a0<a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-3\/\" target=\"_blank\" rel=\"noopener\">through iterators<\/a>,\u00a0<a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-2\/\" target=\"_blank\" rel=\"noopener\">manipulating data,<\/a> <a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-4\/\" target=\"_blank\" rel=\"noopener\">handling errors<\/a>, <a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-5\/\" target=\"_blank\" rel=\"noopener\">prepared statements<\/a> and other <a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-6\/\" target=\"_blank\" rel=\"noopener\">advanced topics<\/a>. The final topic to cover is a newly added feature to 7.1 that enables JavaScript library storage options.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Hierarchical JavaScript library storage<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Another major change in 7.1 is the JavaScript library storage having changed from flat to hierarchical.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This means that alongside global libraries, you can now have libraries created under a bucket and a scope.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Global libraries are available to use as both global and scope UDFs, while scope libraries are only available to use for scope UDFs created under the same scope as the library.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This means that while, by using global libraries, you can continue to treat libraries as an extension of your application, and by publishing a new library you automatically amend all its instances in different buckets and scope, if you only have been granted the <em>manage_external_scope_functions<\/em> privilege and want to create libraries for your own use, you can.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Or maybe as an application developer you may want to create scope specific implementations of certain global libraries, for instance a local instance with new code that you are implementing for the next release of your application.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Manipulating libraries<\/span><\/h2>\n<p><span style=\"font-weight: 400\">The <em>jsevaluator<\/em> REST endpoint used to manipulate libraries shown at the beginning of this blog has been extended to accept buckets and scope.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This is done like so:<\/span><\/p>\n<p><strong>Global library<\/strong><\/p>\n<pre class=\"left-set:true nums:false wrap:true lang:sh decode:true\">curl -v -X POST https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math -u Administrator:password -d 'function add(a, b) { let data = a + b; return data; }'<\/pre>\n<p><strong>Scope library<\/strong><\/p>\n<pre class=\"left-set:true nums:false wrap:true lang:sh decode:true\">curl -v -X POST 'https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math?bucket=b1&amp;scope=s1' -u Administrator:password -d 'function add(a, b) { let data = a + b; return data; }'<\/pre>\n<p><span style=\"font-weight: 400\">Clearly the authenticated user needs to have appropriate privileges to create libraries at each level: <\/span><em><span style=\"font-weight: 400\">manage_external_functions<\/span><\/em><span style=\"font-weight: 400\"> for global libraries and <\/span><em><span style=\"font-weight: 400\">manage_external_scope_functions<\/span><\/em><span style=\"font-weight: 400\"> for scope libraries.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Also, the referenced bucket and scope must already exist.<\/span><\/p>\n<p><span style=\"font-weight: 400\">At the cost of repeating myself, the curl command must contain the whole library, not just any new function you may want to define: please remember that any change that you make is reflected across all UDFs using the library, and any function you may drop by mistake will potentially affect multiple scopes and UDFs, so be careful.<\/span><\/p>\n<p><span style=\"font-weight: 400\">For the avoidance of doubt, this applies to the UI too.\u00a0<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Referencing libraries in UDFs<\/span><\/h2>\n<p><span style=\"font-weight: 400\">All the examples of <\/span><span style=\"font-weight: 400\">CREATE FUNCTION<\/span><span style=\"font-weight: 400\"> seen so far use a simple string identifier for the library, meaning that they use a global library.<\/span><\/p>\n<p><em><span style=\"font-weight: 400\">CREATE FUNCTION \u2026 LANGUAGE JAVASCRIPT<\/span><\/em><span style=\"font-weight: 400\"> supports the following three formats for library names:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">An identifier, e.g., <\/span><span style=\"font-weight: 400\">&#8220;<em>library<\/em>&#8220;<\/span><span style=\"font-weight: 400\">: this points to a global library<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">The <\/span><em><span style=\"font-weight: 400\">.\/<\/span><\/em><span style=\"font-weight: 400\"> notation, e.g., <\/span><span style=\"font-weight: 400\">&#8220;<em>.\/library<\/em>&#8220;<\/span><span style=\"font-weight: 400\">: this means a library under the current <em>query_context<\/em>, a global library for a global function and the corresponding scope library for a scope function<\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">A full scope path, e.g., <\/span><span style=\"font-weight: 400\">&#8220;<em>bucket\/scope\/library<\/em>&#8220;<\/span><span style=\"font-weight: 400\">: scope functions can point to scope libraries, but please be aware that cross scope pollination is not allowed &#8211; scope functions can only point to libraries in their own scope.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400\">Any other library name format is disallowed.<\/span><\/p>\n<h2>Curl tips and tricks<\/h2>\n<h3><span style=\"font-weight: 400\">Amending libraries<\/span><\/h3>\n<p><span style=\"font-weight: 400\">When amending libraries using the REST API, for example to add a new function, be mindful that you have to submit the whole library again: if you just pass the text of the new function, all the previous functions will be obliterated!<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Useful command line switches and options<\/span><\/h3>\n<p><span style=\"font-weight: 400\">The curl <\/span><em><span style=\"font-weight: 400\">\u2013data-binary<\/span><\/em><span style=\"font-weight: 400\"> command line option instructs curl not to discard newlines and carriage returns.<\/span><\/p>\n<p><span style=\"font-weight: 400\">This is useful in that, if your function returns an error, the error message will contain the correct line information for the error, vs using <\/span><em><span style=\"font-weight: 400\">-d<\/span><\/em><span style=\"font-weight: 400\"> or <\/span><em><span style=\"font-weight: 400\">\u2013data<\/span><\/em><span style=\"font-weight: 400\"> will cause the errors to always be reported to have occurred in line 1!<\/span><\/p>\n<p><span style=\"font-weight: 400\">As an example:<\/span><\/p>\n<pre class=\"left-set:true nums:false nums-toggle:false wrap:true lang:sh decode:true\">curl -v -X POST https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math -u Administrator:password \u2014data-binary 'function add(a, b) {\r\n    let data = a + b;\r\n    return data;\r\n}'<\/pre>\n<p><span style=\"font-weight: 400\">Another useful feature is to save the contents of a library in a file, and then reference the file in the <\/span><em><span style=\"font-weight: 400\">\u2013data-binary<\/span><\/em><span style=\"font-weight: 400\"> (or <\/span><em><span style=\"font-weight: 400\">-d<\/span><\/em><span style=\"font-weight: 400\">) argument, by prefixing with a &#8220;<em>@<\/em>&#8220;, for instance:<\/span><\/p>\n<pre class=\"left-set:true nums:false nums-toggle:false wrap:true lang:sh decode:true\">curl -v -X POST https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math -u Administrator:password \u2013data-binary '@path\/to\/file'<\/pre>\n<p><span style=\"font-weight: 400\">Where your library would be saved in path\/to\/file.<\/span><\/p>\n<h2>Conclusion<\/h2>\n<p><span style=\"font-weight: 400\">This brief post shows how these new storage options give you flexibility in how to hierarchically manage the code you build and deploy. <\/span><\/p>\n<p><span style=\"font-weight: 400\">One final update for you, while there are code-based references to the term <em>N1QL<\/em> in this series, we refer to the query language as <em>SQL++<\/em> &#8211; an extension of the SQL standard. Queries in Couchbase are generally SQL++ based, allowing you to build on your standard SQL querying knowledge but apply it to JSON documents and more. Going forward, you can likely swap the term <em>N1QL<\/em> for <em>SQL++<\/em> and you&#8217;ll be all caught up to date.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Thank you for following along with this series of N1QL and JavaScript topics, a summary list of topics is included below for your reference. <\/span><\/p>\n<h3>Resources<\/h3>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/sqlplusplus\/\" target=\"_blank\" rel=\"noopener\">SQL++ &#8211; The next-generation query language for managin JSON data<\/a><\/li>\n<li>SQL++\/N1QL to JavaScript and Back Series:\n<ol>\n<li>SQL++\u00a0 <a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-1-introduction\/\" target=\"_blank\" rel=\"noopener\">functions<\/a><\/li>\n<li>Processing documents <a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-3\/\" target=\"_blank\" rel=\"noopener\">through iterators<\/a><\/li>\n<li><a href=\"https:\/\/blog.couchbase.com\/from-n1ql-to-javascript-and-back-part-2\/\" target=\"_blank\" rel=\"noopener\">Manipulating data<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-4\/\" target=\"_blank\" rel=\"noopener\">Handling errors<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-5\/\" target=\"_blank\" rel=\"noopener\">Prepared statements<\/a><\/li>\n<li>and other <a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-6\/\" target=\"_blank\" rel=\"noopener\">advanced topics<\/a><\/li>\n<li>This post, <a href=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\" target=\"_blank\" rel=\"noopener\">hierarchical JavaScript library storage<\/a><\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In previous blogs, we covered executing N1QL (SQL++) from JavaScript\u00a0functions, processing documents\u00a0through iterators,\u00a0manipulating data, handling errors, prepared statements and other advanced topics. The final topic to cover is a newly added feature to 7.1 that enables JavaScript library storage options. [&hellip;]<\/p>\n","protected":false},"author":1782,"featured_media":13855,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,9327,1812],"tags":[1543,8911],"ppma_author":[8924],"class_list":["post-13854","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-javascript","category-n1ql-query","tag-javascript","tag-udf"],"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>From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage - 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\/from-n1ql-to-javascript-and-back-part-7\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage\" \/>\n<meta property=\"og:description\" content=\"In previous blogs, we covered executing N1QL (SQL++) from JavaScript\u00a0functions, processing documents\u00a0through iterators,\u00a0manipulating data, handling errors, prepared statements and other advanced topics. The final topic to cover is a newly added feature to 7.1 that enables JavaScript library storage options. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-11-03T20:43:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-12T08:42:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439-1024x683.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"683\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Marco Greco, Software Architect, 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=\"Marco Greco, Software Architect, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\"},\"author\":{\"name\":\"Marco Greco, Software Architect, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/2b5184a7cdb443ff2897aff0866cd6fd\"},\"headline\":\"From N1QL to JavaScript and Back &#8211; Part 7: Hierarchical JavaScript Storage\",\"datePublished\":\"2022-11-03T20:43:33+00:00\",\"dateModified\":\"2024-09-12T08:42:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\"},\"wordCount\":811,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png\",\"keywords\":[\"javascript\",\"User Defined Function (UDF)\"],\"articleSection\":[\"Couchbase Server\",\"JavaScript\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\",\"name\":\"From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png\",\"datePublished\":\"2022-11-03T20:43:33+00:00\",\"dateModified\":\"2024-09-12T08:42:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png\",\"width\":1500,\"height\":1000,\"caption\":\"SQL++ N1QL JavaScript library hierarchical\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"From N1QL to JavaScript and Back &#8211; Part 7: Hierarchical JavaScript Storage\"}]},{\"@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\/2b5184a7cdb443ff2897aff0866cd6fd\",\"name\":\"Marco Greco, Software Architect, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/707c967b795fd71b6330f6d3118cf308\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g\",\"caption\":\"Marco Greco, Software Architect, Couchbase\"},\"description\":\"In a previous life, Marco used to be CTO, radiation physicist, software architect, sysadmin, DBA, trainer and general handyman at Italy's largest radiation theraphy practice. Having switched career and country, he spent more than two decades in various support and development positions in Informix first and IBM later, before finally taking the plunge and joining Couchbase, to help them make gold out of N1QL. He holds several patents and has authored open source projects of his own.\",\"sameAs\":[\"https:\/\/github.com\/marcogrecopriolo\",\"https:\/\/www.linkedin.com\/in\/marco-greco-7665308\/\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/marcocouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage - 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\/from-n1ql-to-javascript-and-back-part-7\/","og_locale":"en_US","og_type":"article","og_title":"From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage","og_description":"In previous blogs, we covered executing N1QL (SQL++) from JavaScript\u00a0functions, processing documents\u00a0through iterators,\u00a0manipulating data, handling errors, prepared statements and other advanced topics. The final topic to cover is a newly added feature to 7.1 that enables JavaScript library storage options. [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/","og_site_name":"The Couchbase Blog","article_published_time":"2022-11-03T20:43:33+00:00","article_modified_time":"2024-09-12T08:42:30+00:00","og_image":[{"width":1024,"height":683,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439-1024x683.png","type":"image\/png"}],"author":"Marco Greco, Software Architect, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Marco Greco, Software Architect, Couchbase","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/"},"author":{"name":"Marco Greco, Software Architect, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/2b5184a7cdb443ff2897aff0866cd6fd"},"headline":"From N1QL to JavaScript and Back &#8211; Part 7: Hierarchical JavaScript Storage","datePublished":"2022-11-03T20:43:33+00:00","dateModified":"2024-09-12T08:42:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/"},"wordCount":811,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png","keywords":["javascript","User Defined Function (UDF)"],"articleSection":["Couchbase Server","JavaScript","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/","url":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/","name":"From N1QL to JavaScript and Back - Part 7: Hierarchical JavaScript Storage - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png","datePublished":"2022-11-03T20:43:33+00:00","dateModified":"2024-09-12T08:42:30+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/image_2022-11-03_115612115-e1667516621439.png","width":1500,"height":1000,"caption":"SQL++ N1QL JavaScript library hierarchical"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/from-n1ql-to-javascript-and-back-part-7\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"From N1QL to JavaScript and Back &#8211; Part 7: Hierarchical JavaScript Storage"}]},{"@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\/2b5184a7cdb443ff2897aff0866cd6fd","name":"Marco Greco, Software Architect, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/707c967b795fd71b6330f6d3118cf308","url":"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g","caption":"Marco Greco, Software Architect, Couchbase"},"description":"In a previous life, Marco used to be CTO, radiation physicist, software architect, sysadmin, DBA, trainer and general handyman at Italy's largest radiation theraphy practice. Having switched career and country, he spent more than two decades in various support and development positions in Informix first and IBM later, before finally taking the plunge and joining Couchbase, to help them make gold out of N1QL. He holds several patents and has authored open source projects of his own.","sameAs":["https:\/\/github.com\/marcogrecopriolo","https:\/\/www.linkedin.com\/in\/marco-greco-7665308\/"],"url":"https:\/\/www.couchbase.com\/blog\/author\/marcocouchbase-com\/"}]}},"authors":[{"term_id":8924,"user_id":1782,"is_guest":0,"slug":"marcocouchbase-com","display_name":"Marco Greco, Software Architect, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g","author_category":"","last_name":"Greco","first_name":"Marco","job_title":"","user_url":"","description":"In a previous life, Marco used to be CTO, radiation physicist, software architect, sysadmin, DBA, trainer and general handyman at Italy's largest radiation theraphy practice.\r\n\r\nHaving switched career and country, he spent more than two decades in various support and development positions in Informix first and IBM later, before finally taking the plunge and joining Couchbase, to help them make gold out of N1QL.\r\n\r\nHe holds several patents and has authored open source projects of his own."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13854","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\/1782"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=13854"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/13854\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13855"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=13854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=13854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=13854"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=13854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}