{"id":9720,"date":"2021-08-25T00:00:09","date_gmt":"2021-08-25T07:00:09","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=9720"},"modified":"2025-06-13T23:34:39","modified_gmt":"2025-06-14T06:34:39","slug":"n1ql-user-defined-functions","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-user-defined-functions\/","title":{"rendered":"O N1QL agora oferece suporte a fun\u00e7\u00f5es definidas pelo usu\u00e1rio"},"content":{"rendered":"<p><strong>Declarative query languages have been a major gear shift<\/strong> in the world of database engines.<\/p>\n<p>The <a href=\"https:\/\/www.couchbase.com\/sqlplusplus\/?ref=blog\" target=\"_blank\" rel=\"noopener\">SQL++ query language<\/a> (formerly N1QL) is primarily a declarative query language. You tell the query what to get and N1QL works out the rest of the details of how to make it happen.<\/p>\n<p>Yet, the ability to programmatically instruct your database query comes in handy in several situations. After all, you know your own business logic \u2013 N1QL does not.<\/p>\n<p>Enter <em>user-defined functions (UDFs)<\/em>. UDFs give you more control over a particular query and let you instruct the query language on how certain tasks are done. <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-server-7-0-release\/?ref=blog\" target=\"_blank\" rel=\"noopener\">The Couchbase Server 7.0 release<\/a> includes user-defined functions for the N1QL query language.<\/p>\n<p>N1QL is rather agnostic as far as underlying programming languages go. Rather than specifying its own procedural language, N1QL employs a <em>Language Manager<\/em>, meaning that it is already designed to support a multitude of guest languages.<\/p>\n<p>For now, the languages supported are <em>inline<\/em>, an internal language that allows you to code any valid N1QL expression (including subqueries) and <em>JavaScript<\/em>. Let\u2019s begin by comparing these two supported languages for N1QL UDFs.<\/p>\n<h2>N1QL UDF Example: Basic Usage<\/h2>\n<p>In order to add your business logic, you have to create functions, like the <em>inline<\/em> example below:<\/p>\n<pre class=\"lang:mysql decode:true \">CREATE FUNCTION add(arg1, arg2) { arg1 + arg2 }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>You can then use your business logic freely wherever an expression is allowed, or directly through the `EXECUTE FUNCTION` statement:<\/p>\n<pre class=\"lang:default decode:true\">select add(1, 2)\r\nEXECUTE FUNCTION add(1, 2)\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>And when you no longer have a use for it, you just drop it:<\/p>\n<pre class=\"lang:default decode:true \">DROP FUNCTION add\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h2>N1QL UDF Example: JavaScript<\/h2>\n<p>Creating and dropping JavaScript user-defined functions is slightly more convoluted, for reasons that will become apparent in the next section.<\/p>\n<p>JavaScript UDFs are technically <em>external<\/em> functions. That\u2019s because they\u2019re written in a different language and are executed in process different from the N1QL Query Service.<\/p>\n<p>Your first step is to create the JavaScript code:<\/p>\n<pre class=\"lang:default 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; }'\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>Next, create the N1QL function:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION javascriptAdd(a, b) LANGUAGE javascript AS \"add\" AT \"math\"\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>Once created, you can create and drop JavaScript UDFs exactly like inline ones. When you no longer need the library, you can delete it using this command:<\/p>\n<pre class=\"lang:default decode:true \">curl -v -X DELETE https:\/\/localhost:8093\/evaluator\/v1\/libraries\/math -u Administrator:password\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h2>New in Couchbase 7.0: User-Defined Functions for Scopes &amp; Collections<\/h2>\n<p>One of the major features of the Couchbase Server 7.0 release is the introduction of <a href=\"https:\/\/www.couchbase.com\/blog\/scopes-and-collections-for-modern-multi-tenant-applications-couchbase-7-0\/?ref=blog\" target=\"_blank\" rel=\"noopener\">Scopes and Collections<\/a> to further help you organize your <a href=\"https:\/\/www.couchbase.com\/blog\/json-database\/?ref=blog\" target=\"_blank\" rel=\"noopener\">JSON<\/a> documents. Collections are storage units for a group of similar documents, and Scopes are larger storage units holding multiple Collections, allowing you to partition applications.<\/p>\n<p>With Scopes and Collections, <a href=\"https:\/\/www.couchbase.com\/products\/server\/?ref=blog\" target=\"_blank\" rel=\"noopener\"><br \/>\nCouchbase Server<\/a> \u2013 a document database \u2013 now offers all the strengths of the relational model \u2013 schema, tables, columns \u2013 without any of its weaknesses.<\/p>\n<p><em>Quick side-step:<\/em> In order to allow backward compatibility, the Query Service now has a `query_context` REST API parameter that indicates which Bucket and Scope should be used to resolve relative keyspace names, for example:<\/p>\n<pre class=\"lang:default decode:true \">cbq&gt; \\set -query_context \"default:travel-sample.scope1\";\r\ncbq&gt; select * from airlines;\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>In the statement above, the `SELECT` statement resolves `airlines` to the Collection named `default:travel-sample.scope1.airlines`.<\/p>\n<p>Okay, now back to user-defined functions:<\/p>\n<p>The logic behind Scopes and Collections with UDFs is that you could have a development, pre-production and production environments of the same application in three different Scopes, where three copies of the same application are deployed with the same logic. Conversely, you could have Scopes contain different deployments of the same application where different business logic is required (e.g., online shops where different discount or delivery structures are applied, or an accountancy application, where different taxation rules are applied).<\/p>\n<p>In the first case, having a global definition for individual functions suffices because the business logic is the same. But in order to support the second case, UDFs had to be partitioned across Scopes. Each Scope can have its own instance of the same UDF, each with different logic.<\/p>\n<p>It\u2019s also worth noting that Couchbase Server 7.0 does not force you to switch over to Scopes and Collections, so it was important that UDFs not be tied to the Collections feature.<\/p>\n<h3>A Note on Global UDFs<\/h3>\n<p>Global UDFs are not dependent on Scopes, meaning that they are backward compatible with UDFs introduced in 6.5.<\/p>\n<p>If you are not using Collections, you don\u2019t have to do anything special to use them.<br \/>\nGlobal UDFs are referenced using a two-part fully qualified name, as below:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION default:bucket1.scope1.func1()  { 0 };\r\nEXECUTE FUNCTION default:bucket1.scope1.func1();\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>The Importance of the query_context Parameter<\/h3>\n<p>\u201cOkay, now I am confused,\u201d I hear you say. \u201cWhich functions were you using then in the previous examples? The names weren\u2019t fully qualified.\u201d<\/p>\n<p>The answer lies in the `query_context` REST API parameter setting: if the `query_context` is unset, the N1QL parser resolves the name to <em>global<\/em> functions. If the `query_context` is set, the parser uses the `query_context` value to resolve the names to the relevant Scope functions, much like it did with non-qualified keyspace names.<\/p>\n<p>You can seamlessly deploy your application against Scopes or against Buckets just by changing the setting of the `query_context` REST API parameter.<\/p>\n<h3>Object Resolution Inside Functions<\/h3>\n<p>When user-defined functions reference fully qualified objects, there\u2019s no ambiguity as to which object they mean:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION func { (SELECT * FROM default:bucket1.scope1.collection1) };\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>The next question is, how do functions resolve objects referenced inside them? For instance:<\/p>\n<pre class=\"lang:default decode:true\">CREATE FUNCTION func1() { func2() };\r\nCREATE FUNCTION default:func3 { (SELECT * FROM keyspace1) };\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>The key here is the principle of least surprise: during execution, user-defined functions switch query context to the path under which they were created and always reference objects inside that path.<\/p>\n<p>It does not matter if you called them with a relative or a fully qualified path, a function called with the same parameters always returns the same results, which is taken from the same objects.<\/p>\n<p>In the first example above, `func2()` would resolve to a global or a Scope function depending on the `query_context` setting at creation time.<\/p>\n<p>For `func3()`, `keyspace1` would be the Bucket `keyspace1`.<\/p>\n<h3>Mixing Global vs. Scope Functions<\/h3>\n<p>There\u2019s nothing to stop you from using global UDFs alongside the Collections feature: just use the fully qualified names.<\/p>\n<p>Similarly, if you want to use a Scope function created in a different Scope, all you have to do is reference it directly.<\/p>\n<h3>JavaScript Functions, Revisited<\/h3>\n<p>Here\u2019s why JavaScript functions should be split into two parts \u2013 i.e., a body and a separate function definition:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>When you create the body separately from the function definition, you can reuse the same body in multiple places. The same function in multiple places could reference the same body, and when the body is edited or redefined, then that change automatically applies across all related function definitions.<\/li>\n<li>Similarly, this pattern is also important when it comes to dropping or deleting functions. When you need to drop one instance of a function, the body needs to stay in place if it\u2019s used by other instances.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Tips &amp; Tricks for Using N1QL User-Defined Functions in Couchbase 7.0<\/h2>\n<h3>Naming Your UDFs<\/h3>\n<p>UDF names are identifiers and cannot match predefined function names. If the names <em>do<\/em> match, then the predefined function takes precedence, meaning your UDF doesn\u2019t get used.<\/p>\n<p>If you want to use a predefined function name (for some reason), you have to fully qualify it when you reference it. For example:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION length(arg) { 0 };\r\nSELECT default:length(type) FROM `travel-sample`;\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>UDF Parameters<\/h3>\n<p>N1QL user-defined functions support three types of parameter lists:<\/p>\n<ol>\n<li>Empty parameters\n<pre class=\"lang:default decode:true \">CREATE FUNCTION func1() { 0 }\r\n<\/pre>\n<p>The function takes no parameters. Any parameter passed results in an error.<\/li>\n<li>Variadic parameters\n<pre class=\"lang:default decode:true \">CREATE FUNCTION func1(...) { array_length(args) }\r\n<\/pre>\n<p>Three dots denote a variadic function. It can take any number of parameters of any type. The parameters are contained in an array names `args`.<\/li>\n<li>Named parameters\n<pre class=\"lang:default decode:true \">CREATE FUNCTION func1(arg1) { arg1 }\r\n<\/pre>\n<p>The parameters are not typed, but the number of arguments passed is enforced.<\/li>\n<\/ol>\n<h3>Some Tips on Overloading &amp; Type Handling<\/h3>\n<p>Untyped parameters and variadic functions are the closest that Couchbase will get to function overloading: where the same function is defined multiple times with a different parameter list \u2013 or different parameter types \u2013 in order to be able to operate differently depending on the input.<\/p>\n<p>I would recommend this N1QL strategy instead: Have a single function which checks the arguments received and acts accordingly.<\/p>\n<p>An example of a variadic function follows:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION variadic(...) { CASE WHEN array_length(args) != 1 THEN \"wrong args: \" || to_string(array_length(args))  WHEN type(args[0]) = \"string\" THEN args[0] ELSE \"wrong type \" || type(args[0]) || \": \" || to_string(args[0]) END }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>And a non-variadic function:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION twoargs(arg1, arg2) { CASE WHEN type(arg1) != \"string\" THEN \"wrong arg1 \" || type(arg1) || \": \" || to_string(arg1) WHEN type(arg2) != \"string\" THEN \"wrong arg2 \" || type(arg2) || \": \" || to_string(arg2) ELSE arg1 || arg2 END }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>Parameter Names vs. Document Fields<\/h3>\n<p>Consider the following function:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION docsOfType(type) { (SELECT * from `travel-sample` WHERE type=type) }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>Notice how the function declared a parameter that happens to have the same name as a document field? Clearly that function doesn\u2019t achieve its intent \u2013 as there\u2019s no way to distinguish in between the two.<\/p>\n<p>Here\u2019s how you use parameters names to get around this problem: Parameter names override document fields (either way, the above query returns all documents in the `travel-sample` dataset).<\/p>\n<p>In order to access document fields, you have two choices. Either refer to the document field with their fully qualified name, as you can see below:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION docsOfType(type) { (SELECT * from `travel-sample` WHERE travel-sample.type=type) }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>Or, remove the ambiguity by renaming the parameter, as below:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION docsOfType(vType) { (SELECT * from `travel-sample` WHERE type=vType) }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>Return Values with UDFs<\/h3>\n<p>User-defined functions only return one value of any type. If you need to return more than one value, return an array or an object.<\/p>\n<p><strong>But watch your return types!<\/strong> Remember that `SELECT` statements executed inside UDFs return arrays, so even if your `SELECT` returns just one document, it is a one-element array. Instead, return the first element of the array.<\/p>\n<p>For example, this function below doesn\u2019t do what you want:<\/p>\n<pre class=\"lang:default decode:true\">CREATE FUNCTION tsample() { (SELECT * FROM `travel-sample` LIMIT 1) }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>But this one does:<\/p>\n<pre class=\"lang:default decode:true \">CREATE FUNCTION tsample1st() { (SELECT * FROM `travel-sample` LIMIT 1)[0] }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>Using UDF return values as data to query<\/h3>\n<p>At the opposite side of the spectrum, since UDFs can return arrays, they can be gainfully used to dynamically generate data to be queried, much like your would do in Relational engines with concepts like Table Functions or Collection Derived Tables, as in the following example<\/p>\n<pre class=\"\">SELECT * FROM tsample() sample<\/pre>\n<p>Although the example function selects data from a bucket, any valid way to construct an array can be used to generate the data.<\/p>\n<h3>When You Need to Update an Existing Function<\/h3>\n<p>Sometimes you need to redefine a function. The `OR REPLACE` clause of the `CREATE FUNCTION` statement allows you to do just that in a single step:<\/p>\n<pre class=\"lang:default decode:true \">CREATE OR REPLACE FUNCTION tsample1st() { (SELECT * FROM `travel-sample` LIMIT 1)[0] }\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h3>User Access Privileges<\/h3>\n<p>Any N1QL statement executed inside a UDF is executed with the same privileges as the user who submitted the request. As such, your user needs to have appropriate privileges to access all of the objects that the given UDF references.<\/p>\n<p>On top of all this, the user also needs to have the privilege to execute functions. Different privilege levels exist for internal, external, global and Scope-level functions. In order to create and drop functions, the user needs to have been granted permission to manage functions. For example:<\/p>\n<pre class=\"lang:default decode:true \">GRANT query_manage_global_functions TO user1;\r\nGRANT query_execute_external_functions ON default:test.scope1 TO user1;\r\n<\/pre>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<h2>Conclusion<\/h2>\n<p>I hope you found this post helpful in understanding when and how to leverage N1QL user-defined functions with Couchbase 7.0. Check out the documentation for <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/n1ql\/n1ql-language-reference\/userfun.html?ref=blog\" target=\"_blank\" rel=\"noopener\"> more information on user-defined functions<\/a>, context on <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/n1ql\/n1ql-intro\/sysinfo.html?ref=blog#logical-hierarchy\" target=\"_blank\" rel=\"noopener\">N1QL objects and `query_context`<\/a> and <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/learn\/security\/roles.html?ref=blog#manage-global-functions\" target=\"_blank\" rel=\"noopener\">security roles for UDFs<\/a>.<\/p>\n<div class=\"wp-block-spacer\" style=\"height: 30px;\" aria-hidden=\"true\"><\/div>\n<div style=\"text-align: center;\"><strong>Itching to try out UDFs for yourself?<br \/>\n<a href=\"https:\/\/www.couchbase.com\/downloads\/?ref=blog\" target=\"_blank\" rel=\"noopener\">Take Couchbase 7 for a spin<\/a><\/strong><\/div>\n<div class=\"wp-block-spacer\" style=\"height: 15px;\" aria-hidden=\"true\"><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Declarative query languages have been a major gear shift in the world of database engines. The SQL++ query language (formerly N1QL) is primarily a declarative query language. You tell the query what to get and N1QL works out the rest [&hellip;]<\/p>\n","protected":false},"author":1782,"featured_media":11779,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1816,9327,1812],"tags":[1867,2312,1543,1261,8911],"ppma_author":[8924],"class_list":["post-9720","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-server","category-javascript","category-n1ql-query","tag-business-logic","tag-document-database","tag-javascript","tag-json","tag-udf"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>N1QL Now Supports User-Defined Functions<\/title>\n<meta name=\"description\" content=\"Discover what\u2019s possible with the introduction of user-defined functions to the N1QL query language in Couchbase 7, including these UDF tips and tricks.\" \/>\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\/pt\/n1ql-user-defined-functions\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"N1QL Now Supports User-Defined Functions\" \/>\n<meta property=\"og:description\" content=\"Discover what\u2019s possible with the introduction of user-defined functions to the N1QL query language in Couchbase 7, including these UDF tips and tricks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-user-defined-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-08-25T07:00:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:34:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0-social.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"418\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Marco Greco, Software Architect, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0-social.jpg\" \/>\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=\"9 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/\"},\"author\":{\"name\":\"Marco Greco, Software Architect, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/2b5184a7cdb443ff2897aff0866cd6fd\"},\"headline\":\"N1QL Now Supports User-Defined Functions\",\"datePublished\":\"2021-08-25T07:00:09+00:00\",\"dateModified\":\"2025-06-14T06:34:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/\"},\"wordCount\":1771,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2020\\\/12\\\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg\",\"keywords\":[\"Business Logic\",\"document database\",\"javascript\",\"JSON\",\"User Defined Function (UDF)\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Server\",\"JavaScript\",\"SQL++ \\\/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/\",\"name\":\"N1QL Now Supports User-Defined Functions\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2020\\\/12\\\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg\",\"datePublished\":\"2021-08-25T07:00:09+00:00\",\"dateModified\":\"2025-06-14T06:34:39+00:00\",\"description\":\"Discover what\u2019s possible with the introduction of user-defined functions to the N1QL query language in Couchbase 7, including these UDF tips and tricks.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2020\\\/12\\\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2020\\\/12\\\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg\",\"width\":1200,\"height\":628,\"caption\":\"Learn these tips and tricks for creating user-defined functions (UDFs) with the N1QL query language\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/n1ql-user-defined-functions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"N1QL Now Supports User-Defined 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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g707c967b795fd71b6330f6d3118cf308\",\"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\\\/pt\\\/author\\\/marcocouchbase-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"O N1QL agora oferece suporte a fun\u00e7\u00f5es definidas pelo usu\u00e1rio","description":"Descubra o que \u00e9 poss\u00edvel com a introdu\u00e7\u00e3o de fun\u00e7\u00f5es definidas pelo usu\u00e1rio na linguagem de consulta N1QL no Couchbase 7, incluindo estas dicas e truques de UDF.","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\/pt\/n1ql-user-defined-functions\/","og_locale":"pt_BR","og_type":"article","og_title":"N1QL Now Supports User-Defined Functions","og_description":"Discover what\u2019s possible with the introduction of user-defined functions to the N1QL query language in Couchbase 7, including these UDF tips and tricks.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/n1ql-user-defined-functions\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-08-25T07:00:09+00:00","article_modified_time":"2025-06-14T06:34:39+00:00","og_image":[{"width":800,"height":418,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0-social.jpg","type":"image\/jpeg"}],"author":"Marco Greco, Software Architect, Couchbase","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0-social.jpg","twitter_misc":{"Written by":"Marco Greco, Software Architect, Couchbase","Est. reading time":"9 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/"},"author":{"name":"Marco Greco, Software Architect, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/2b5184a7cdb443ff2897aff0866cd6fd"},"headline":"N1QL Now Supports User-Defined Functions","datePublished":"2021-08-25T07:00:09+00:00","dateModified":"2025-06-14T06:34:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/"},"wordCount":1771,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg","keywords":["Business Logic","document database","javascript","JSON","User Defined Function (UDF)"],"articleSection":["Best Practices and Tutorials","Couchbase Server","JavaScript","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/","url":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/","name":"O N1QL agora oferece suporte a fun\u00e7\u00f5es definidas pelo usu\u00e1rio","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg","datePublished":"2021-08-25T07:00:09+00:00","dateModified":"2025-06-14T06:34:39+00:00","description":"Descubra o que \u00e9 poss\u00edvel com a introdu\u00e7\u00e3o de fun\u00e7\u00f5es definidas pelo usu\u00e1rio na linguagem de consulta N1QL no Couchbase 7, incluindo estas dicas e truques de UDF.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2020\/12\/user-defined-functions-n1ql-query-language-couchbase-7-0.jpg","width":1200,"height":628,"caption":"Learn these tips and tricks for creating user-defined functions (UDFs) with the N1QL query language"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/n1ql-user-defined-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"N1QL Now Supports User-Defined Functions"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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, arquiteto de software, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/e6be0ee56851d2f71a554731d5edd5c820069680f0a810b47f094091c58bc553?s=96&d=mm&r=g707c967b795fd71b6330f6d3118cf308","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\/pt\/author\/marcocouchbase-com\/"}]}},"acf":[],"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","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/9720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/1782"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=9720"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/9720\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/11779"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=9720"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=9720"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=9720"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=9720"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}