{"id":5060,"date":"2025-12-18T10:00:32","date_gmt":"2025-12-18T18:00:32","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/"},"modified":"2025-12-18T10:00:32","modified_gmt":"2025-12-18T18:00:32","slug":"talk-to-your-data-a-udf-that-speaks-your-language","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/talk-to-your-data-a-udf-that-speaks-your-language\/","title":{"rendered":"Talk to Your Data: A UDF That Speaks Your Language"},"content":{"rendered":"<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT u.name, COUNT(o.id) AS total_orders<br \/>\nFROM `commerce`.sales.users AS u<br \/>\nJOIN `commerce`.sales.orders AS o ON u.id = o.user_id<br \/>\nWHERE o.status = &#8220;completed&#8221;<br \/>\nAND DATE_DIFF_STR(NOW_STR(), o.order_date, &#8220;day&#8221;) &lt;= 30<br \/>\nGROUP BY u.name<br \/>\nORDER BY total_orders DESC<br \/>\nLIMIT 5;<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>The query above provides valuable insights from your data that&#8217;s stored in Couchbase about your top five users who generated the most completed orders within the past 30 days. But what if you\u2019re not an advanced SQL++ developer and need the answers by 11 p.m. for a report? You then need to wait for a developer to write a SQL++ query and get you the answers.<\/span><\/p>\n\n\n\n<p><span>Alternatively, consider a case where you need to do some ad hoc debugging to address questions like:<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span>Are there any documents where the date the order was delivered is missing?<\/span><\/li>\n\n\n<li><span>Does that mean that the order was cancelled? Or did we misplace the order and the order never got delivered? Or was everything ok, but we simply missed adding the order_delivered value in the field?<\/span><\/li>\n\n<\/ul>\n\n\n\n<p><span>In this case, you not only need to search the\u00a0 order_delivered field, but also look at order_cancelled or investigate comments to figure out if it was misplaced, etc. So the query to be written isn\u2019t simple or straightforward.\u00a0<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT<br \/>\n    o.orderId,<br \/>\n    o.orderDate,<br \/>\n    o.order_cancelled,<br \/>\n    o.order_delivered,<br \/>\n    o.comments,<\/p>\n<p>    CASE<br \/>\n        WHEN o.order_cancelled = TRUE THEN &#8220;Order was cancelled&#8221;<br \/>\n        WHEN ANY c IN o.comments SATISFIES LOWER(c) LIKE &#8220;%misplac%&#8221;<br \/>\n                                    OR LOWER(c) LIKE &#8220;%lost%&#8221; THEN &#8220;Order may have been misplaced&#8221;<br \/>\n        WHEN ANY c IN o.comments SATISFIES LOWER(c) LIKE &#8220;%deliver%&#8221; THEN &#8220;Delivered but field not updated&#8221;<br \/>\n        ELSE &#8220;Reason unknown \u2014 investigate&#8221;<br \/>\n    END AS reason<br \/>\nFROM `commerce`.`sales`.`orders` AS o<br \/>\nWHERE o.order_delivered IS MISSING OR o.order_delivered IS NULL;<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>In such cases, it would help if you had a reliable assistant available 24&#215;7 to get all these answers. The UDF described in this blog is such an assistant. It accepts your questions in the most natural way and returns results in JSON. Behind the scenes, it connects to a model of your choice, along with your API key, to convert your thoughts into SQL++ and then executes it. And all you need to invoke this assistant is to use the UDF.<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT NL2SQL(<br \/>\n  [\u201c`commerce`.`sales`.`orders`\u201d],<br \/>\n  &#8220;Are there any documents where the order_delivered date is missing?and if so why?&#8221;,<br \/>\n  &#8220;&#8221;,<br \/>\n  &#8220;https:\/\/api.openai.com\/v1\/chat\/completions&#8221;,<br \/>\n  &#8220;gpt-4o-2024-05-13&#8221;<br \/>\n) ;<br \/>\n[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><b>How It Works<\/b><\/h3>\n\n\n\n<p><span>1. <b>Set up the library.<\/b><br>\nYou first create a JavaScript library used by the UDF.<\/span><\/p>\n\n\n\n<p><span>Library:<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]\/*<br \/>\ninput:<\/p>\n<p>keyspaces: an array of strings, each string represents a keyspaces &#8220;bucket.scope.collection&#8221; with proper escaping using grave-accent quote wherever required<br \/>\nprompt: users natural language request<br \/>\napikey: your openai api key<br \/>\nmodel: string representing the model&#8217;s name, see https:\/\/platform.openai.com\/docs\/api-reference\/completions\/create#completions-create-model for more details<\/p>\n<p>output:<br \/>\nchat-completions api response with the generated sql statement<br \/>\n*\/<\/p>\n<p>function inferencer(k) {<br \/>\n   var infq = N1QL(&#8220;SELECT t.properties FROM(INFER &#8220;+k+ &#8220;) as t&#8221;) ;<br \/>\n   var res=[]<br \/>\n   for(const doc of infq) {<br \/>\n       res.push(doc)<br \/>\n   }<\/p>\n<p>    return res[0];<br \/>\n}<\/p>\n<p>function nl2sql(keyspaces, prompt, apikey, modelapi, model) {<\/p>\n<p>   collectionSchema = {}<br \/>\n   for(const k in keyspaces) {<br \/>\n       c = inferencer(keyspaces[k])<br \/>\n       collectionSchema[keyspaces[k]] = c<br \/>\n   }<\/p>\n<p>   collectionSchemaStr = JSON.stringify(collectionSchema)<\/p>\n<p>   promptContent = `Information:nCollection&#8217;s schema: ${collectionSchemaStr}nnPrompt: &#8220;${prompt}&#8221;nnThe query context is set.nnBased on the above Information, write valid SQL++ and return only the statement and no explanation. For retrieval, use aliases. Use UNNEST from the FROM clause when appropriate. nnIf you&#8217;re sure the Prompt can&#8217;t be used to generate a query, first say &#8220;#ERR:&#8221; and then explain why not.`<\/p>\n<p>    data = {&#8220;messages&#8221;:[{&#8220;role&#8221;:&#8221;system&#8221;,&#8221;content&#8221;:&#8221;You are a Couchbase Capella expert. Your task is to create valid queries to retrieve or create data based on the provided Information.nnApproach this task step-by-step and take your time.&#8221;},{&#8220;role&#8221;:&#8221;user&#8221;,&#8221;content&#8221;:promptContent}],<br \/>\n        &#8220;model&#8221;: model,<br \/>\n        &#8220;temperature&#8221;:0,<br \/>\n        &#8220;max_tokens&#8221;:1024,<br \/>\n        &#8220;stream&#8221;:false}<\/p>\n<p>var dataStr = JSON.stringify(data)<br \/>\n    .replace(\/\\\/g, &#8220;\\\\&#8221;)    \/\/ escape backslashes<br \/>\n    .replace(\/&#8221;\/g, &#8216;\\&#8221;&#8216;);     \/\/ escape quotes<\/p>\n<p>    var completionsurl = modelapi<\/p>\n<p>   var q= `SELECT CURL(&#8220;${completionsurl}&#8221;, {<br \/>\n        &#8220;request&#8221;: &#8220;POST&#8221;,<br \/>\n        &#8220;header&#8221;: [&#8220;Authorization: Bearer ${apikey}&#8221;, &#8220;Content-type: application\/json&#8221;],<br \/>\n        &#8220;data&#8221;: &#8220;${dataStr}&#8221;<br \/>\n    }) AS result;`<\/p>\n<p>    var completionsq = N1QL(q);<\/p>\n<p>    var res = []<br \/>\n   for(const doc of completionsq) {<br \/>\n       res.push(doc);<br \/>\n     }<\/p>\n<p>  try {<br \/>\n    content = res[0].result.choices[0].message.content<br \/>\n  } catch(e) {<br \/>\n    return res;<br \/>\n  } <\/p>\n<p>  stmt = content.trim().substring(7, content.length-4)<\/p>\n<p>  isSelect = (stmt.substring(0,6).toLowerCase())===&#8221;select&#8221;<br \/>\n  if(isSelect === false){<br \/>\n      return {<br \/>\n          &#8220;generated_statement&#8221;: stmt<br \/>\n      }<br \/>\n  }<\/p>\n<p>  var runq = N1QL(stmt);<\/p>\n<p>   var rrun = []<br \/>\n  for(const doc of runq) {<br \/>\n      rrun.push(doc)<br \/>\n  }<\/p>\n<p>  return {<br \/>\n      &#8220;generated_statement&#8221;: stmt,<br \/>\n      &#8220;results&#8221;: rrun<br \/>\n  }<\/p>\n<p>}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>2. <b>Upload the library.<\/b><br>\nRun the curl command after copying the provided library code into a file, i.e., usingailib.js. <\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]curl -X POST https:\/\/localhost:9499\/evaluator\/v1\/libraries\/usingailib<br \/>\n&#8211;data-binary @usingailib.js -u Administrator:password[\/crayon]<\/p>\n\n\n\n<p><span>3. <b>Create the UDF.<\/b><br>\nUse the create function statement below to create the UDF once you have created the library:<\/span><\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]CREATE OR REPLACE FUNCTION NL2SQL(keyspaces, prompt, apikey, modelapi, model)<br \/>\nLANGUAGE JAVASCRIPT AS &#8220;nl2sql&#8221; AT &#8220;usingailib&#8221;;[\/crayon]<\/p>\n\n\n\n<p><span>NL2SQL() now acts as your multilingual translator between human language and Couchbase\u2019s query engine. You simply give it some context and a natural language request, and it returns a response.<\/span><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the UDF Thinks<\/h3>\n\n\n\n<p><span>Under the hood, it uses your preferred model when invoking the UDF to understand your intent and generate a query that Couchbase can execute.<\/span><\/p>\n\n\n\n<p><span>The advantage of using the chat completions API means you could simply plug in a model from other providers that are compliant with the same API spec. You can use your own private LLM or known ones from Open AI, Gemini, Claude, etc.<\/span><\/p>\n\n\n\n<p><span>The invoked UDF requires the following information from you:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><em>keyspaces<\/em> \u2013 An array of strings, each representing a Couchbase keyspace (bucket.scope.collection).Use grave accent quotes where needed to escape special names (like `travel-sample`.inventory.route). This tells the UDF where to look for your data.<\/li>\n\n\n<li><em>prompt<\/em> \u2013 Your request in plain English (or any other language).<br>\nExample: &#8220;Show me all users who made a purchase in the last 24 hours.&#8221;<\/li>\n\n\n<li><em>apikey<\/em> \u2013 Your API key used for authenticating with the model endpoint.<\/li>\n\n\n<li><em>model endpoint<\/em> \u2013 e.g., Open AI compliant chat completions URL.<\/li>\n\n\n<li><em>model<\/em> \u2013 The name of the model you want to use from the provider.<br>\ne.g., &#8220;gpt-4o-2024-05-13&#8221;<\/li>\n\n<\/ol>\n\n\n\n<p><span>There are also several available functions in the library:<\/span><\/p>\n\n\n\n<p><strong>inferencer()<\/strong><\/p>\n\n\n\n<p>Before generating a query, the UDF first tries to understand your data. The inferencer() helper function calls Couchbase\u2019s INFER statement to retrieve a collection\u2019s schema:<\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]function inferencer(k) {<br \/>\n   var infq = N1QL(&#8220;SELECT t.properties FROM (INFER &#8221; + k + &#8220;) AS t&#8221;);<br \/>\n   var res = [];<br \/>\n   for (const doc of infq) {<br \/>\n       res.push(doc);<br \/>\n   }<br \/>\n   return res[0];<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p>This schema is used to help the AI understand what kind of data lives inside each collection.<\/p>\n\n\n\n<p><strong>The main function: nl2sql()<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Collects all schemas for the given keyspaces using the inferencer(). Constructs a prompt that includes: the inferred schema, your natural language query, and a Couchbase prompt to nudge the LLM.<\/li>\n\n\n<li>Sends it to the LLM.<\/li>\n\n\n<li>Extracts the generated SQL++ from the model\u2019s response.<\/li>\n\n\n<li>Executes it directly if it\u2019s a SELECT statement and returns both the generated SQL++ statement and the query results.<\/li>\n\n<\/ul>\n\n\n\n<p><span>The reason for not executing non-select statements is that you don\u2019t want this UDF to insert, update, or delete documents in a collection without you verifying it. So the SQL++ statement lets you execute it after it\u2019s been verified.<\/span><\/p>\n\n\n\n<p>Example use case:<\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT default:NL2SQL(<br \/>\n  [&#8220;`travel-sample`.inventory.hotel&#8221;],<br \/>\n  &#8220;Give me hotels in San Francisco that have free parking and free breakfast and a rating of more than 3&#8221;,  &#8220;&#8221;,<br \/>\n  &#8220;https:\/\/api.openai.com\/v1\/chat\/completions&#8221;,<br \/>\n  &#8220;gpt-4o-2024-05-13&#8221;<br \/>\n);<br \/>\n[\/crayon]<\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]Result:<br \/>\n[{<br \/>\n    &#8220;$1&#8221;: {<br \/>\n        &#8220;generated_statement&#8221;: &#8220;SELECT h.name, h.address, h.city, h.state, h.country, h.free_parking, h.free_breakfast, r.ratings.OverallnFROM `travel-sample`.inventory.hotel AS hnUNNEST h.reviews AS rnWHERE h.city = &#8220;San Francisco&#8221;n  AND h.free_parking = truen  AND h.free_breakfast = truen  AND r.ratings.Overall &gt; 3;&#8221;,<br \/>\n        &#8220;results&#8221;: [{<br \/>\n                &#8220;Overall&#8221;: 4,<br \/>\n                &#8220;address&#8221;: &#8220;520 Church St&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Parker House&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n            {<br \/>\n                &#8220;Overall&#8221;: 4,<br \/>\n                &#8220;address&#8221;: &#8220;520 Church St&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Parker House&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n            {<br \/>\n                &#8220;Overall&#8221;: 5,<br \/>\n                &#8220;address&#8221;: &#8220;520 Church St&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Parker House&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n            {<br \/>\n                &#8220;Overall&#8221;: 4,<br \/>\n                &#8220;address&#8221;: &#8220;520 Church St&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Parker House&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n            {<br \/>\n                &#8220;Overall&#8221;: 5,<br \/>\n                &#8220;address&#8221;: &#8220;465 Grant Ave&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Grant Plaza Hotel&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n            {<br \/>\n                &#8220;Overall&#8221;: 5,<br \/>\n                &#8220;address&#8221;: &#8220;465 Grant Ave&#8221;,<br \/>\n                &#8220;city&#8221;: &#8220;San Francisco&#8221;,<br \/>\n                &#8220;country&#8221;: &#8220;United States&#8221;,<br \/>\n                &#8220;free_breakfast&#8221;: true,<br \/>\n                &#8220;free_parking&#8221;: true,<br \/>\n                &#8220;name&#8221;: &#8220;Grant Plaza Hotel&#8221;,<br \/>\n                &#8220;state&#8221;: &#8220;California&#8221;<br \/>\n            },<br \/>\n&#8230;<br \/>\n[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Experimenting with models from other providers<\/h3>\n\n\n\n<p>The next example uses Gemini\u2019s Open AI-compatible API. You simply change the model provider\u2019s URL from the previous Open AI API to Gemini\u2019s API. Also, be sure to change the model parameter to a model it recognizes. Of course, you need to also update the api-key from Open AI\u2019s key to Gemini\u2019s key.<\/p>\n\n\n<p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT NL2SQL(<br \/>\n  [&#8220;`travel-sample`.inventory.hotel&#8221;],<br \/>\n  &#8220;Show me hotels in France&#8221;,<br \/>\n  &#8220;&#8221;,<br \/>\n  &#8220;https:\/\/generativelanguage.googleapis.com\/v1beta\/openai\/chat\/completions&#8221;,<br \/>\n  &#8220;gemini-2.0-flash&#8221;<br \/>\n)as p;<br \/>\n[\/crayon]<\/p>\n\n\n\n<p>The following illustrates the result:<\/p>\n\n\n\n<p><p>[crayon lang=&#8221;default&#8221; decode=&#8221;true&#8221;]SELECT<br \/>\n    o.orderId,<br \/>\n    o.orderDate,<br \/>\n    o.order_cancelled,<br \/>\n    o.order_delivered,<br \/>\n    o.comments,<\/p>\n<p>    CASE<br \/>\n        WHEN o.order_cancelled = TRUE THEN &#8220;Order was cancelled&#8221;<br \/>\n        WHEN ANY c IN o.comments SATISFIES LOWER(c) LIKE &#8220;%misplac%&#8221;<br \/>\n                                    OR LOWER(c) LIKE &#8220;%lost%&#8221; THEN &#8220;Order may have been misplaced&#8221;<br \/>\n        WHEN ANY c IN o.comments SATISFIES LOWER(c) LIKE &#8220;%deliver%&#8221; THEN &#8220;Delivered but field not updated&#8221;<br \/>\n        ELSE &#8220;Reason unknown \u2014 investigate&#8221;<br \/>\n    END AS reason<br \/>\nFROM `commerce`.`sales`.`orders` AS o<br \/>\nWHERE o.order_delivered IS MISSING OR o.order_delivered IS NULL;<br \/>\n[\/crayon]<\/p>\n0<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>This blog provides a glimpse into how you can leverage AI to interact with your data in Couchbase. With this UDF, natural language querying becomes a reality &#8211; no SQL++ expertise required. It is model-agnostic and safe for production queries.<\/p>\n\n\n\n<p>And this is just the beginning. In the future, we hope to extend it to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Image \u2192 SQL++<\/li>\n\n\n<li>Voice \u2192 SQL++<\/li>\n\n\n<li>Agent-like pipelines<\/li>\n\n<\/ul>\n\n\n\n<p>\u2026 all running inside Couchbase workflows.<\/p>\n\n\n\n<p><strong>References<\/strong><br>\nCapella IQ: <a href=\"https:\/\/docs.couchbase.com\/cloud\/get-started\/capella-iq\/get-started-with-iq.html\">https:\/\/docs.couchbase.com\/cloud\/get-started\/capella-iq\/get-started-with-iq.html<\/a><br>\nChat completions APIs:<br>\n<a href=\"https:\/\/platform.openai.com\/docs\/api-reference\/chat\">https:\/\/platform.openai.com\/docs\/api-reference\/chat<\/a><br>\n<a href=\"https:\/\/ai.google.dev\/gemini-api\/docs\/openai#rest\">https:\/\/ai.google.dev\/gemini-api\/docs\/openai#rest<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The query above provides valuable insights from your data that&#8217;s stored in Couchbase about your top five users who generated the most completed orders within the past 30 days. But what if you\u2019re not an advanced SQL++ developer and need the answers by 11 p.m. for a report? You then need to wait for a [&hellip;]<\/p>\n","protected":false},"author":84423,"featured_media":5057,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[54],"tags":[],"ppma_author":[683],"class_list":["post-5060","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Talk to Your Data: A UDF That Speaks Your Language - 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\/pt\/talk-to-your-data-a-udf-that-speaks-your-language\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Talk to Your Data: A UDF That Speaks Your Language\" \/>\n<meta property=\"og:description\" content=\"The query above provides valuable insights from your data that&#8217;s stored in Couchbase about your top five users who generated the most completed orders within the past 30 days. But what if you\u2019re not an advanced SQL++ developer and need the answers by 11 p.m. for a report? You then need to wait for a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/talk-to-your-data-a-udf-that-speaks-your-language\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-18T18:00:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1-1024x536.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"536\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Gaurav Jayaraj - Software Engineer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Gaurav Jayaraj - Software Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/\"},\"author\":{\"name\":\"Gaurav Jayaraj - Software Engineer\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/546cec92f77cbb0b09f9b973fd1c8d42\"},\"headline\":\"Talk to Your Data: A UDF That Speaks Your Language\",\"datePublished\":\"2025-12-18T18:00:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/\"},\"wordCount\":1817,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png\",\"articleSection\":[\"Couchbase Server\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/\",\"name\":\"Talk to Your Data: A UDF That Speaks Your Language - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png\",\"datePublished\":\"2025-12-18T18:00:32+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/talk-to-your-data-a-udf-that-speaks-your-language\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Talk to Your Data: A UDF That Speaks Your Language\"}]},{\"@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\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/546cec92f77cbb0b09f9b973fd1c8d42\",\"name\":\"Gaurav Jayaraj - Software Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g9f655fda3d24fd49bccf33982dd15670\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g\",\"caption\":\"Gaurav Jayaraj - Software Engineer\"},\"description\":\"Gaurav Jayaraj is an intern in the Query team at Couchbase R&amp;D. Gaurav is pursuing his Bachelors in Computer Science from PES University, Bangalore.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/gauravjayaraj\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Talk to Your Data: A UDF That Speaks Your Language - 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\/pt\/talk-to-your-data-a-udf-that-speaks-your-language\/","og_locale":"pt_BR","og_type":"article","og_title":"Talk to Your Data: A UDF That Speaks Your Language","og_description":"The query above provides valuable insights from your data that&#8217;s stored in Couchbase about your top five users who generated the most completed orders within the past 30 days. But what if you\u2019re not an advanced SQL++ developer and need the answers by 11 p.m. for a report? You then need to wait for a [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/talk-to-your-data-a-udf-that-speaks-your-language\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-12-18T18:00:32+00:00","og_image":[{"width":1024,"height":536,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1-1024x536.png","type":"image\/png"}],"author":"Gaurav Jayaraj - Software Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Gaurav Jayaraj - Software Engineer","Est. reading time":"4 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/"},"author":{"name":"Gaurav Jayaraj - Software Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/546cec92f77cbb0b09f9b973fd1c8d42"},"headline":"Talk to Your Data: A UDF That Speaks Your Language","datePublished":"2025-12-18T18:00:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/"},"wordCount":1817,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png","articleSection":["Couchbase Server"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/","url":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/","name":"Talk to Your Data: A UDF That Speaks Your Language - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png","datePublished":"2025-12-18T18:00:32+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/Talk-to-Your-Data_-A-UDF-That-Speaks-Your-Language-1.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/talk-to-your-data-a-udf-that-speaks-your-language\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Talk to Your Data: A UDF That Speaks Your Language"}]},{"@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\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/546cec92f77cbb0b09f9b973fd1c8d42","name":"Gaurav Jayaraj - Software Engineer","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g9f655fda3d24fd49bccf33982dd15670","url":"https:\/\/secure.gravatar.com\/avatar\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bbb46a14616fc13176b2496886166e68b3348a81653303d78f7df462db2eb5a1?s=96&d=mm&r=g","caption":"Gaurav Jayaraj - Software Engineer"},"description":"Gaurav Jayaraj is an intern in the Query team at Couchbase R&amp;D. Gaurav is pursuing his Bachelors in Computer Science from PES University, Bangalore.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/gauravjayaraj\/"}]}},"acf":[],"authors":[{"term_id":683,"user_id":84423,"is_guest":0,"slug":"gauravjayaraj","display_name":"Gaurav Jayaraj - Software Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/unnamed-2-5.jpg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/unnamed-2-5.jpg"},"0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/5060","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\/84423"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=5060"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/5060\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/5057"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=5060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=5060"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=5060"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=5060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}