CINXE.COM
Recursive Query Processing in SQL++ (N1QL) Function
<!DOCTYPE html> <html lang="en-US"> <head><meta charset="UTF-8"><script>if(navigator.userAgent.match(/MSIE|Internet Explorer/i)||navigator.userAgent.match(/Trident\/7\..*?rv:11/i)){var href=document.location.href;if(!href.match(/[?&]nowprocket/)){if(href.indexOf("?")==-1){if(href.indexOf("#")==-1){document.location.href=href+"?nowprocket=1"}else{document.location.href=href.replace("#","?nowprocket=1#")}}else{if(href.indexOf("#")==-1){document.location.href=href+"&nowprocket=1"}else{document.location.href=href.replace("#","&nowprocket=1#")}}}}</script><script>(()=>{class RocketLazyLoadScripts{constructor(){this.v="1.2.6",this.triggerEvents=["keydown","mousedown","mousemove","touchmove","touchstart","touchend","wheel"],this.userEventHandler=this.t.bind(this),this.touchStartHandler=this.i.bind(this),this.touchMoveHandler=this.o.bind(this),this.touchEndHandler=this.h.bind(this),this.clickHandler=this.u.bind(this),this.interceptedClicks=[],this.interceptedClickListeners=[],this.l(this),window.addEventListener("pageshow",(t=>{this.persisted=t.persisted,this.everythingLoaded&&this.m()})),this.CSPIssue=sessionStorage.getItem("rocketCSPIssue"),document.addEventListener("securitypolicyviolation",(t=>{this.CSPIssue||"script-src-elem"!==t.violatedDirective||"data"!==t.blockedURI||(this.CSPIssue=!0,sessionStorage.setItem("rocketCSPIssue",!0))})),document.addEventListener("DOMContentLoaded",(()=>{this.k()})),this.delayedScripts={normal:[],async:[],defer:[]},this.trash=[],this.allJQueries=[]}p(t){document.hidden?t.t():(this.triggerEvents.forEach((e=>window.addEventListener(e,t.userEventHandler,{passive:!0}))),window.addEventListener("touchstart",t.touchStartHandler,{passive:!0}),window.addEventListener("mousedown",t.touchStartHandler),document.addEventListener("visibilitychange",t.userEventHandler))}_(){this.triggerEvents.forEach((t=>window.removeEventListener(t,this.userEventHandler,{passive:!0}))),document.removeEventListener("visibilitychange",this.userEventHandler)}i(t){"HTML"!==t.target.tagName&&(window.addEventListener("touchend",this.touchEndHandler),window.addEventListener("mouseup",this.touchEndHandler),window.addEventListener("touchmove",this.touchMoveHandler,{passive:!0}),window.addEventListener("mousemove",this.touchMoveHandler),t.target.addEventListener("click",this.clickHandler),this.L(t.target,!0),this.S(t.target,"onclick","rocket-onclick"),this.C())}o(t){window.removeEventListener("touchend",this.touchEndHandler),window.removeEventListener("mouseup",this.touchEndHandler),window.removeEventListener("touchmove",this.touchMoveHandler,{passive:!0}),window.removeEventListener("mousemove",this.touchMoveHandler),t.target.removeEventListener("click",this.clickHandler),this.L(t.target,!1),this.S(t.target,"rocket-onclick","onclick"),this.M()}h(){window.removeEventListener("touchend",this.touchEndHandler),window.removeEventListener("mouseup",this.touchEndHandler),window.removeEventListener("touchmove",this.touchMoveHandler,{passive:!0}),window.removeEventListener("mousemove",this.touchMoveHandler)}u(t){t.target.removeEventListener("click",this.clickHandler),this.L(t.target,!1),this.S(t.target,"rocket-onclick","onclick"),this.interceptedClicks.push(t),t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.M()}O(){window.removeEventListener("touchstart",this.touchStartHandler,{passive:!0}),window.removeEventListener("mousedown",this.touchStartHandler),this.interceptedClicks.forEach((t=>{t.target.dispatchEvent(new MouseEvent("click",{view:t.view,bubbles:!0,cancelable:!0}))}))}l(t){EventTarget.prototype.addEventListenerWPRocketBase=EventTarget.prototype.addEventListener,EventTarget.prototype.addEventListener=function(e,i,o){"click"!==e||t.windowLoaded||i===t.clickHandler||t.interceptedClickListeners.push({target:this,func:i,options:o}),(this||window).addEventListenerWPRocketBase(e,i,o)}}L(t,e){this.interceptedClickListeners.forEach((i=>{i.target===t&&(e?t.removeEventListener("click",i.func,i.options):t.addEventListener("click",i.func,i.options))})),t.parentNode!==document.documentElement&&this.L(t.parentNode,e)}D(){return new Promise((t=>{this.P?this.M=t:t()}))}C(){this.P=!0}M(){this.P=!1}S(t,e,i){t.hasAttribute&&t.hasAttribute(e)&&(event.target.setAttribute(i,event.target.getAttribute(e)),event.target.removeAttribute(e))}t(){this._(this),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this.R.bind(this)):this.R()}k(){let t=[];document.querySelectorAll("script[type=rocketlazyloadscript][data-rocket-src]").forEach((e=>{let i=e.getAttribute("data-rocket-src");if(i&&!i.startsWith("data:")){0===i.indexOf("//")&&(i=location.protocol+i);try{const o=new URL(i).origin;o!==location.origin&&t.push({src:o,crossOrigin:e.crossOrigin||"module"===e.getAttribute("data-rocket-type")})}catch(t){}}})),t=[...new Map(t.map((t=>[JSON.stringify(t),t]))).values()],this.T(t,"preconnect")}async R(){this.lastBreath=Date.now(),this.j(this),this.F(this),this.I(),this.W(),this.q(),await this.A(this.delayedScripts.normal),await this.A(this.delayedScripts.defer),await this.A(this.delayedScripts.async);try{await this.U(),await this.H(this),await this.J()}catch(t){console.error(t)}window.dispatchEvent(new Event("rocket-allScriptsLoaded")),this.everythingLoaded=!0,this.D().then((()=>{this.O()})),this.N()}W(){document.querySelectorAll("script[type=rocketlazyloadscript]").forEach((t=>{t.hasAttribute("data-rocket-src")?t.hasAttribute("async")&&!1!==t.async?this.delayedScripts.async.push(t):t.hasAttribute("defer")&&!1!==t.defer||"module"===t.getAttribute("data-rocket-type")?this.delayedScripts.defer.push(t):this.delayedScripts.normal.push(t):this.delayedScripts.normal.push(t)}))}async B(t){if(await this.G(),!0!==t.noModule||!("noModule"in HTMLScriptElement.prototype))return new Promise((e=>{let i;function o(){(i||t).setAttribute("data-rocket-status","executed"),e()}try{if(navigator.userAgent.indexOf("Firefox/")>0||""===navigator.vendor||this.CSPIssue)i=document.createElement("script"),[...t.attributes].forEach((t=>{let e=t.nodeName;"type"!==e&&("data-rocket-type"===e&&(e="type"),"data-rocket-src"===e&&(e="src"),i.setAttribute(e,t.nodeValue))})),t.text&&(i.text=t.text),i.hasAttribute("src")?(i.addEventListener("load",o),i.addEventListener("error",(function(){i.setAttribute("data-rocket-status","failed-network"),e()})),setTimeout((()=>{i.isConnected||e()}),1)):(i.text=t.text,o()),t.parentNode.replaceChild(i,t);else{const i=t.getAttribute("data-rocket-type"),s=t.getAttribute("data-rocket-src");i?(t.type=i,t.removeAttribute("data-rocket-type")):t.removeAttribute("type"),t.addEventListener("load",o),t.addEventListener("error",(i=>{this.CSPIssue&&i.target.src.startsWith("data:")?(console.log("WPRocket: data-uri blocked by CSP -> fallback"),t.removeAttribute("src"),this.B(t).then(e)):(t.setAttribute("data-rocket-status","failed-network"),e())})),s?(t.removeAttribute("data-rocket-src"),t.src=s):t.src="data:text/javascript;base64,"+window.btoa(unescape(encodeURIComponent(t.text)))}}catch(i){t.setAttribute("data-rocket-status","failed-transform"),e()}}));t.setAttribute("data-rocket-status","skipped")}async A(t){const e=t.shift();return e&&e.isConnected?(await this.B(e),this.A(t)):Promise.resolve()}q(){this.T([...this.delayedScripts.normal,...this.delayedScripts.defer,...this.delayedScripts.async],"preload")}T(t,e){var i=document.createDocumentFragment();t.forEach((t=>{const o=t.getAttribute&&t.getAttribute("data-rocket-src")||t.src;if(o&&!o.startsWith("data:")){const s=document.createElement("link");s.href=o,s.rel=e,"preconnect"!==e&&(s.as="script"),t.getAttribute&&"module"===t.getAttribute("data-rocket-type")&&(s.crossOrigin=!0),t.crossOrigin&&(s.crossOrigin=t.crossOrigin),t.integrity&&(s.integrity=t.integrity),i.appendChild(s),this.trash.push(s)}})),document.head.appendChild(i)}j(t){let e={};function i(i,o){return e[o].eventsToRewrite.indexOf(i)>=0&&!t.everythingLoaded?"rocket-"+i:i}function o(t,o){!function(t){e[t]||(e[t]={originalFunctions:{add:t.addEventListener,remove:t.removeEventListener},eventsToRewrite:[]},t.addEventListener=function(){arguments[0]=i(arguments[0],t),e[t].originalFunctions.add.apply(t,arguments)},t.removeEventListener=function(){arguments[0]=i(arguments[0],t),e[t].originalFunctions.remove.apply(t,arguments)})}(t),e[t].eventsToRewrite.push(o)}function s(e,i){let o=e[i];e[i]=null,Object.defineProperty(e,i,{get:()=>o||function(){},set(s){t.everythingLoaded?o=s:e["rocket"+i]=o=s}})}o(document,"DOMContentLoaded"),o(window,"DOMContentLoaded"),o(window,"load"),o(window,"pageshow"),o(document,"readystatechange"),s(document,"onreadystatechange"),s(window,"onload"),s(window,"onpageshow");try{Object.defineProperty(document,"readyState",{get:()=>t.rocketReadyState,set(e){t.rocketReadyState=e},configurable:!0}),document.readyState="loading"}catch(t){console.log("WPRocket DJE readyState conflict, bypassing")}}F(t){let e;function i(e){return t.everythingLoaded?e:e.split(" ").map((t=>"load"===t||0===t.indexOf("load.")?"rocket-jquery-load":t)).join(" ")}function o(o){function s(t){const e=o.fn[t];o.fn[t]=o.fn.init.prototype[t]=function(){return this[0]===window&&("string"==typeof arguments[0]||arguments[0]instanceof String?arguments[0]=i(arguments[0]):"object"==typeof arguments[0]&&Object.keys(arguments[0]).forEach((t=>{const e=arguments[0][t];delete arguments[0][t],arguments[0][i(t)]=e}))),e.apply(this,arguments),this}}o&&o.fn&&!t.allJQueries.includes(o)&&(o.fn.ready=o.fn.init.prototype.ready=function(e){return t.domReadyFired?e.bind(document)(o):document.addEventListener("rocket-DOMContentLoaded",(()=>e.bind(document)(o))),o([])},s("on"),s("one"),t.allJQueries.push(o)),e=o}o(window.jQuery),Object.defineProperty(window,"jQuery",{get:()=>e,set(t){o(t)}})}async H(t){const e=document.querySelector("script[data-webpack]");e&&(await async function(){return new Promise((t=>{e.addEventListener("load",t),e.addEventListener("error",t)}))}(),await t.K(),await t.H(t))}async U(){this.domReadyFired=!0;try{document.readyState="interactive"}catch(t){}await this.G(),document.dispatchEvent(new Event("rocket-readystatechange")),await this.G(),document.rocketonreadystatechange&&document.rocketonreadystatechange(),await this.G(),document.dispatchEvent(new Event("rocket-DOMContentLoaded")),await this.G(),window.dispatchEvent(new Event("rocket-DOMContentLoaded"))}async J(){try{document.readyState="complete"}catch(t){}await this.G(),document.dispatchEvent(new Event("rocket-readystatechange")),await this.G(),document.rocketonreadystatechange&&document.rocketonreadystatechange(),await this.G(),window.dispatchEvent(new Event("rocket-load")),await this.G(),window.rocketonload&&window.rocketonload(),await this.G(),this.allJQueries.forEach((t=>t(window).trigger("rocket-jquery-load"))),await this.G();const t=new Event("rocket-pageshow");t.persisted=this.persisted,window.dispatchEvent(t),await this.G(),window.rocketonpageshow&&window.rocketonpageshow({persisted:this.persisted}),this.windowLoaded=!0}m(){document.onreadystatechange&&document.onreadystatechange(),window.onload&&window.onload(),window.onpageshow&&window.onpageshow({persisted:this.persisted})}I(){const t=new Map;document.write=document.writeln=function(e){const i=document.currentScript;i||console.error("WPRocket unable to document.write this: "+e);const o=document.createRange(),s=i.parentElement;let n=t.get(i);void 0===n&&(n=i.nextSibling,t.set(i,n));const c=document.createDocumentFragment();o.setStart(c,0),c.appendChild(o.createContextualFragment(e)),s.insertBefore(c,n)}}async G(){Date.now()-this.lastBreath>45&&(await this.K(),this.lastBreath=Date.now())}async K(){return document.hidden?new Promise((t=>setTimeout(t))):new Promise((t=>requestAnimationFrame(t)))}N(){this.trash.forEach((t=>t.remove()))}static run(){const t=new RocketLazyLoadScripts;t.p(t)}}RocketLazyLoadScripts.run()})();</script> <!-- <meta name="viewport" content="width=device-width, initial-scale=1"> --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="insight-app-sec-validation" content="8c2f44ef-0f60-427d-a3ac-7297063db717"> <link rel="profile" href="https://gmpg.org/xfn/11"> <link rel="pingback" href="https://www.couchbase.com/blog/xmlrpc.php"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <noscript> </noscript> <link rel="stylesheet" href="https://www.couchbase.com/blog/wp-content/themes/couchbase/css/libraries/satellite-min.css" /> <link data-minify="1" rel="stylesheet" href="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/libraries/autocomplete-theme-classic.css?ver=1732535971" /> <style type="text/css"></style> <script type="rocketlazyloadscript" data-rocket-type="text/javascript">var heateorSlDefaultLang = 'en_US', heateorSlCloseIconPath = 'https://www.couchbase.com/blog/wp-content/plugins/heateor-social-login/public/images/close.png'; var heateorSlSiteUrl = 'https://www.couchbase.com/blog', heateorSlVerified = 0, heateorSlEmailPopup = 0; </script> <script type="rocketlazyloadscript"> var heateorSlLoadingImgPath = 'https://www.couchbase.com/blog/wp-content/plugins/heateor-social-login/public/../images/ajax_loader.gif'; var heateorSlAjaxUrl = 'https://www.couchbase.com/blog/wp-admin/admin-ajax.php'; var heateorSlRedirectionUrl = 'https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/'; var heateorSlRegRedirectionUrl = 'https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/'; </script> <script type="rocketlazyloadscript"> var heateorSlFBKey = '1326406188301490', heateorSlSameTabLogin = '1', heateorSlVerified = 0; var heateorSlAjaxUrl = 'https://www.couchbase.com/blog/wp-admin/admin-ajax.php'; var heateorSlPopupTitle = ''; var heateorSlEmailPopup = 0; var heateorSlEmailAjaxUrl = 'https://www.couchbase.com/blog/wp-admin/admin-ajax.php'; var heateorSlEmailPopupTitle = ''; var heateorSlEmailPopupErrorMsg = ''; var heateorSlEmailPopupUniqueId = ''; var heateorSlEmailPopupVerifyMessage = ''; var heateorSlSteamAuthUrl = ""; var heateorSlCurrentPageUrl = 'https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F'; var heateorMSEnabled = 0; var heateorSlTwitterAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=X&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlFacebookAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Facebook&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlGoogleAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Google&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlYoutubeAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Youtube&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlLineAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Line&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlLiveAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Live&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlVkontakteAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Vkontakte&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlLinkedinAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Linkedin&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlSpotifyAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Spotify&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlKakaoAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Kakao&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlGithubAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Github&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlWordpressAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Wordpress&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlYahooAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Yahoo&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlInstagramAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Instagram&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlDribbbleAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Dribbble&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlTwitchAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Twitch&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlRedditAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Reddit&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlDisqusAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Disqus&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlFoursquareAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Foursquare&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlDropboxAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Dropbox&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlAmazonAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Amazon&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlStackoverflowAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Stackoverflow&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlDiscordAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Discord&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlMailruAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Mailru&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl; var heateorSlYandexAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Yandex&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl ;var heateorSlOdnoklassnikiAuthUrl = heateorSlSiteUrl + "?HeateorSlAuth=Odnoklassniki&heateor_sl_redirect_to=" + heateorSlCurrentPageUrl;</script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript">function heateorSlLoadEvent(e ) {var t=window.onload;if ( typeof window.onload!="function" ) {window.onload=e} else {window.onload=function() {t();e()}}}</script> <meta name='robots' content='index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1' /> <!-- Google Tag Manager for WordPress by gtm4wp.com --> <script data-cfasync="false" data-pagespeed-no-defer> var gtm4wp_datalayer_name = "dataLayer"; var dataLayer = dataLayer || []; </script> <!-- End Google Tag Manager for WordPress by gtm4wp.com --><script type="text/javascript" id="wpp-js" src="https://www.couchbase.com/blog/wp-content/plugins/wordpress-popular-posts/assets/js/wpp.min.js?ver=7.1.0" data-sampling="0" data-sampling-rate="100" data-api-url="https://www.couchbase.com/blog/wp-json/wordpress-popular-posts" data-post-id="14562" data-token="1a03b6a8ca" data-lang="0" data-debug="0"></script> <!-- This site is optimized with the Yoast SEO Premium plugin v23.4 (Yoast SEO v23.9) - https://yoast.com/wordpress/plugins/seo/ --> <title>Recursive Query Processing in SQL++ (N1QL) Function</title><link rel="preload" data-rocket-preload as="style" href="https://fonts.googleapis.com/css?family=Abril%20FatFace%3A400%2C400i%2C700%2C700i%7CAlegreya%3A400%2C400i%2C700%2C700i%7CAlegreya%20Sans%3A400%2C400i%2C700%2C700i%7CAmatic%20SC%3A400%2C400i%2C700%2C700i%7CAnonymous%20Pro%3A400%2C400i%2C700%2C700i%7CArchitects%20Daughter%3A400%2C400i%2C700%2C700i%7CArchivo%3A400%2C400i%2C700%2C700i%7CArchivo%20Narrow%3A400%2C400i%2C700%2C700i%7CAsap%3A400%2C400i%2C700%2C700i%7CBarlow%3A400%2C400i%2C700%2C700i%7CBioRhyme%3A400%2C400i%2C700%2C700i%7CBonbon%3A400%2C400i%2C700%2C700i%7CCabin%3A400%2C400i%2C700%2C700i%7CCairo%3A400%2C400i%2C700%2C700i%7CCardo%3A400%2C400i%2C700%2C700i%7CChivo%3A400%2C400i%2C700%2C700i%7CConcert%20One%3A400%2C400i%2C700%2C700i%7CCormorant%3A400%2C400i%2C700%2C700i%7CCrimson%20Text%3A400%2C400i%2C700%2C700i%7CEczar%3A400%2C400i%2C700%2C700i%7CExo%202%3A400%2C400i%2C700%2C700i%7CFira%20Sans%3A400%2C400i%2C700%2C700i%7CFjalla%20One%3A400%2C400i%2C700%2C700i%7CFrank%20Ruhl%20Libre%3A400%2C400i%2C700%2C700i%7CGreat%20Vibes%3A400%2C400i%2C700%2C700i%7CHeebo%3A400%2C400i%2C700%2C700i%7CIBM%20Plex%3A400%2C400i%2C700%2C700i%7CInconsolata%3A400%2C400i%2C700%2C700i%7CIndie%20Flower%3A400%2C400i%2C700%2C700i%7CInknut%20Antiqua%3A400%2C400i%2C700%2C700i%7CInter%3A400%2C400i%2C700%2C700i%7CKarla%3A400%2C400i%2C700%2C700i%7CLibre%20Baskerville%3A400%2C400i%2C700%2C700i%7CLibre%20Franklin%3A400%2C400i%2C700%2C700i%7CMontserrat%3A400%2C400i%2C700%2C700i%7CNeuton%3A400%2C400i%2C700%2C700i%7CNotable%3A400%2C400i%2C700%2C700i%7CNothing%20You%20Could%20Do%3A400%2C400i%2C700%2C700i%7CNoto%20Sans%3A400%2C400i%2C700%2C700i%7CNunito%3A400%2C400i%2C700%2C700i%7COld%20Standard%20TT%3A400%2C400i%2C700%2C700i%7COxygen%3A400%2C400i%2C700%2C700i%7CPacifico%3A400%2C400i%2C700%2C700i%7CPoppins%3A400%2C400i%2C700%2C700i%7CProza%20Libre%3A400%2C400i%2C700%2C700i%7CPT%20Sans%3A400%2C400i%2C700%2C700i%7CPT%20Serif%3A400%2C400i%2C700%2C700i%7CRakkas%3A400%2C400i%2C700%2C700i%7CReenie%20Beanie%3A400%2C400i%2C700%2C700i%7CRoboto%20Slab%3A400%2C400i%2C700%2C700i%7CRopa%20Sans%3A400%2C400i%2C700%2C700i%7CRubik%3A400%2C400i%2C700%2C700i%7CShadows%20Into%20Light%3A400%2C400i%2C700%2C700i%7CSpace%20Mono%3A400%2C400i%2C700%2C700i%7CSpectral%3A400%2C400i%2C700%2C700i%7CSue%20Ellen%20Francisco%3A400%2C400i%2C700%2C700i%7CTitillium%20Web%3A400%2C400i%2C700%2C700i%7CUbuntu%3A400%2C400i%2C700%2C700i%7CVarela%3A400%2C400i%2C700%2C700i%7CVollkorn%3A400%2C400i%2C700%2C700i%7CWork%20Sans%3A400%2C400i%2C700%2C700i%7CYatra%20One%3A400%2C400i%2C700%2C700i&display=swap" /><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abril%20FatFace%3A400%2C400i%2C700%2C700i%7CAlegreya%3A400%2C400i%2C700%2C700i%7CAlegreya%20Sans%3A400%2C400i%2C700%2C700i%7CAmatic%20SC%3A400%2C400i%2C700%2C700i%7CAnonymous%20Pro%3A400%2C400i%2C700%2C700i%7CArchitects%20Daughter%3A400%2C400i%2C700%2C700i%7CArchivo%3A400%2C400i%2C700%2C700i%7CArchivo%20Narrow%3A400%2C400i%2C700%2C700i%7CAsap%3A400%2C400i%2C700%2C700i%7CBarlow%3A400%2C400i%2C700%2C700i%7CBioRhyme%3A400%2C400i%2C700%2C700i%7CBonbon%3A400%2C400i%2C700%2C700i%7CCabin%3A400%2C400i%2C700%2C700i%7CCairo%3A400%2C400i%2C700%2C700i%7CCardo%3A400%2C400i%2C700%2C700i%7CChivo%3A400%2C400i%2C700%2C700i%7CConcert%20One%3A400%2C400i%2C700%2C700i%7CCormorant%3A400%2C400i%2C700%2C700i%7CCrimson%20Text%3A400%2C400i%2C700%2C700i%7CEczar%3A400%2C400i%2C700%2C700i%7CExo%202%3A400%2C400i%2C700%2C700i%7CFira%20Sans%3A400%2C400i%2C700%2C700i%7CFjalla%20One%3A400%2C400i%2C700%2C700i%7CFrank%20Ruhl%20Libre%3A400%2C400i%2C700%2C700i%7CGreat%20Vibes%3A400%2C400i%2C700%2C700i%7CHeebo%3A400%2C400i%2C700%2C700i%7CIBM%20Plex%3A400%2C400i%2C700%2C700i%7CInconsolata%3A400%2C400i%2C700%2C700i%7CIndie%20Flower%3A400%2C400i%2C700%2C700i%7CInknut%20Antiqua%3A400%2C400i%2C700%2C700i%7CInter%3A400%2C400i%2C700%2C700i%7CKarla%3A400%2C400i%2C700%2C700i%7CLibre%20Baskerville%3A400%2C400i%2C700%2C700i%7CLibre%20Franklin%3A400%2C400i%2C700%2C700i%7CMontserrat%3A400%2C400i%2C700%2C700i%7CNeuton%3A400%2C400i%2C700%2C700i%7CNotable%3A400%2C400i%2C700%2C700i%7CNothing%20You%20Could%20Do%3A400%2C400i%2C700%2C700i%7CNoto%20Sans%3A400%2C400i%2C700%2C700i%7CNunito%3A400%2C400i%2C700%2C700i%7COld%20Standard%20TT%3A400%2C400i%2C700%2C700i%7COxygen%3A400%2C400i%2C700%2C700i%7CPacifico%3A400%2C400i%2C700%2C700i%7CPoppins%3A400%2C400i%2C700%2C700i%7CProza%20Libre%3A400%2C400i%2C700%2C700i%7CPT%20Sans%3A400%2C400i%2C700%2C700i%7CPT%20Serif%3A400%2C400i%2C700%2C700i%7CRakkas%3A400%2C400i%2C700%2C700i%7CReenie%20Beanie%3A400%2C400i%2C700%2C700i%7CRoboto%20Slab%3A400%2C400i%2C700%2C700i%7CRopa%20Sans%3A400%2C400i%2C700%2C700i%7CRubik%3A400%2C400i%2C700%2C700i%7CShadows%20Into%20Light%3A400%2C400i%2C700%2C700i%7CSpace%20Mono%3A400%2C400i%2C700%2C700i%7CSpectral%3A400%2C400i%2C700%2C700i%7CSue%20Ellen%20Francisco%3A400%2C400i%2C700%2C700i%7CTitillium%20Web%3A400%2C400i%2C700%2C700i%7CUbuntu%3A400%2C400i%2C700%2C700i%7CVarela%3A400%2C400i%2C700%2C700i%7CVollkorn%3A400%2C400i%2C700%2C700i%7CWork%20Sans%3A400%2C400i%2C700%2C700i%7CYatra%20One%3A400%2C400i%2C700%2C700i&display=swap" media="print" onload="this.media='all'" /><noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abril%20FatFace%3A400%2C400i%2C700%2C700i%7CAlegreya%3A400%2C400i%2C700%2C700i%7CAlegreya%20Sans%3A400%2C400i%2C700%2C700i%7CAmatic%20SC%3A400%2C400i%2C700%2C700i%7CAnonymous%20Pro%3A400%2C400i%2C700%2C700i%7CArchitects%20Daughter%3A400%2C400i%2C700%2C700i%7CArchivo%3A400%2C400i%2C700%2C700i%7CArchivo%20Narrow%3A400%2C400i%2C700%2C700i%7CAsap%3A400%2C400i%2C700%2C700i%7CBarlow%3A400%2C400i%2C700%2C700i%7CBioRhyme%3A400%2C400i%2C700%2C700i%7CBonbon%3A400%2C400i%2C700%2C700i%7CCabin%3A400%2C400i%2C700%2C700i%7CCairo%3A400%2C400i%2C700%2C700i%7CCardo%3A400%2C400i%2C700%2C700i%7CChivo%3A400%2C400i%2C700%2C700i%7CConcert%20One%3A400%2C400i%2C700%2C700i%7CCormorant%3A400%2C400i%2C700%2C700i%7CCrimson%20Text%3A400%2C400i%2C700%2C700i%7CEczar%3A400%2C400i%2C700%2C700i%7CExo%202%3A400%2C400i%2C700%2C700i%7CFira%20Sans%3A400%2C400i%2C700%2C700i%7CFjalla%20One%3A400%2C400i%2C700%2C700i%7CFrank%20Ruhl%20Libre%3A400%2C400i%2C700%2C700i%7CGreat%20Vibes%3A400%2C400i%2C700%2C700i%7CHeebo%3A400%2C400i%2C700%2C700i%7CIBM%20Plex%3A400%2C400i%2C700%2C700i%7CInconsolata%3A400%2C400i%2C700%2C700i%7CIndie%20Flower%3A400%2C400i%2C700%2C700i%7CInknut%20Antiqua%3A400%2C400i%2C700%2C700i%7CInter%3A400%2C400i%2C700%2C700i%7CKarla%3A400%2C400i%2C700%2C700i%7CLibre%20Baskerville%3A400%2C400i%2C700%2C700i%7CLibre%20Franklin%3A400%2C400i%2C700%2C700i%7CMontserrat%3A400%2C400i%2C700%2C700i%7CNeuton%3A400%2C400i%2C700%2C700i%7CNotable%3A400%2C400i%2C700%2C700i%7CNothing%20You%20Could%20Do%3A400%2C400i%2C700%2C700i%7CNoto%20Sans%3A400%2C400i%2C700%2C700i%7CNunito%3A400%2C400i%2C700%2C700i%7COld%20Standard%20TT%3A400%2C400i%2C700%2C700i%7COxygen%3A400%2C400i%2C700%2C700i%7CPacifico%3A400%2C400i%2C700%2C700i%7CPoppins%3A400%2C400i%2C700%2C700i%7CProza%20Libre%3A400%2C400i%2C700%2C700i%7CPT%20Sans%3A400%2C400i%2C700%2C700i%7CPT%20Serif%3A400%2C400i%2C700%2C700i%7CRakkas%3A400%2C400i%2C700%2C700i%7CReenie%20Beanie%3A400%2C400i%2C700%2C700i%7CRoboto%20Slab%3A400%2C400i%2C700%2C700i%7CRopa%20Sans%3A400%2C400i%2C700%2C700i%7CRubik%3A400%2C400i%2C700%2C700i%7CShadows%20Into%20Light%3A400%2C400i%2C700%2C700i%7CSpace%20Mono%3A400%2C400i%2C700%2C700i%7CSpectral%3A400%2C400i%2C700%2C700i%7CSue%20Ellen%20Francisco%3A400%2C400i%2C700%2C700i%7CTitillium%20Web%3A400%2C400i%2C700%2C700i%7CUbuntu%3A400%2C400i%2C700%2C700i%7CVarela%3A400%2C400i%2C700%2C700i%7CVollkorn%3A400%2C400i%2C700%2C700i%7CWork%20Sans%3A400%2C400i%2C700%2C700i%7CYatra%20One%3A400%2C400i%2C700%2C700i&display=swap" /></noscript><link rel="preload" data-rocket-preload as="style" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700;800&family=Roboto+Mono:wght@500&display=swap" /><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700;800&family=Roboto+Mono:wght@500&display=swap" media="print" onload="this.media='all'" /><noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700;800&family=Roboto+Mono:wght@500&display=swap" /></noscript> <link rel="preload" as="font" href="https://www.couchbase.com/wp-content/themes/couchbase/hco_fonts/woff2/Gotham-Bold_Web.woff2" crossorigin> <link rel="preload" as="font" href="https://www.couchbase.com/wp-content/themes/couchbase/hco_fonts/woff2/Gotham-Book_Web.woff2" crossorigin> <link rel="preload" as="font" href="https://www.couchbase.com/wp-content/themes/couchbase/hco_fonts/woff2/Gotham-Medium_Web.woff2" crossorigin> <meta name="description" content="Users can emulate recursive CTE using JavaScript UDFs with existing infrastructure. This Couchbase blog post demonstrates just how to do that and more!" /> <link rel="canonical" href="https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/" /> <meta property="og:locale" content="en_US" /> <meta property="og:type" content="article" /> <meta property="og:title" content="Recursive Query Processing in SQL++ (N1QL)" /> <meta property="og:description" content="Users can emulate recursive CTE using JavaScript UDFs with existing infrastructure. This Couchbase blog post demonstrates just how to do that and more!" /> <meta property="og:url" content="https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/" /> <meta property="og:site_name" content="The Couchbase Blog" /> <meta property="article:published_time" content="2023-06-23T20:15:52+00:00" /> <meta property="article:modified_time" content="2024-03-01T17:01:33+00:00" /> <meta property="og:image" content="https://www.couchbase.com/blog/wp-content/uploads/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg" /> <meta property="og:image:width" content="1920" /> <meta property="og:image:height" content="2560" /> <meta property="og:image:type" content="image/jpeg" /> <meta name="author" content="Gaurav Jayaraj - Intern, Couchbase R&D" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:label1" content="Written by" /> <meta name="twitter:data1" content="Gaurav Jayaraj - Intern, Couchbase R&D" /> <meta name="twitter:label2" content="Est. reading time" /> <meta name="twitter:data2" content="8 minutes" /> <script type="application/ld+json" class="yoast-schema-graph">{"@context":"https://schema.org","@graph":[{"@type":"Article","@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#article","isPartOf":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/"},"author":{"@id":"https://www.couchbase.com/blog/#/schema/person/926a8f4965c1bcdaef0c4fbd4ee53d46"},"headline":"Recursive Query Processing in SQL++ (N1QL)","datePublished":"2023-06-23T20:15:52+00:00","dateModified":"2024-03-01T17:01:33+00:00","mainEntityOfPage":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/"},"wordCount":1232,"commentCount":0,"publisher":{"@id":"https://www.couchbase.com/blog/#organization"},"image":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#primaryimage"},"thumbnailUrl":"https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg","keywords":["Query Language","recursive queries","UDF"],"articleSection":["Couchbase Server","Data Modeling","JavaScript","SQL++ / N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#respond"]}]},{"@type":"WebPage","@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/","url":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/","name":"Recursive Query Processing in SQL++ (N1QL) Function","isPartOf":{"@id":"https://www.couchbase.com/blog/#website"},"primaryImageOfPage":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#primaryimage"},"image":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#primaryimage"},"thumbnailUrl":"https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg","datePublished":"2023-06-23T20:15:52+00:00","dateModified":"2024-03-01T17:01:33+00:00","description":"Users can emulate recursive CTE using JavaScript UDFs with existing infrastructure. This Couchbase blog post demonstrates just how to do that and more!","breadcrumb":{"@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#primaryimage","url":"https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg","contentUrl":"https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg","width":1920,"height":2560,"caption":"Fibonacci design of staircase by Remy Penet on Unsplash"},{"@type":"BreadcrumbList","@id":"https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://www.couchbase.com/blog/"},{"@type":"ListItem","position":2,"name":"Recursive Query Processing in SQL++ (N1QL)"}]},{"@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/926a8f4965c1bcdaef0c4fbd4ee53d46","name":"Gaurav Jayaraj - Intern, Couchbase R&D","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https://www.couchbase.com/blog/#/schema/person/image/a862981db61c6ac815059faaa791510c","url":"https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=96&d=mm&r=g","contentUrl":"https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=96&d=mm&r=g","caption":"Gaurav Jayaraj - Intern, Couchbase R&D"},"description":"Gaurav Jayaraj is an intern in the Query team at Couchbase R&D. Gaurav is pursuing his Bachelors in Computer Science from PES University, Bangalore.","url":"https://www.couchbase.com/blog/author/gauravjayaraj/"}]}</script> <!-- / Yoast SEO Premium plugin. --> <link href='https://fonts.gstatic.com' crossorigin rel='preconnect' /> <link rel="alternate" type="application/rss+xml" title="The Couchbase Blog » Feed" href="https://www.couchbase.com/blog/feed/" /> <link rel="alternate" type="application/rss+xml" title="The Couchbase Blog » Comments Feed" href="https://www.couchbase.com/blog/comments/feed/" /> <link rel="alternate" type="application/rss+xml" title="The Couchbase Blog » Recursive Query Processing in SQL++ (N1QL) Comments Feed" href="https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/feed/" /> <link rel='stylesheet' id='urvanov_syntax_highlighter-css' href='https://www.couchbase.com/blog/wp-content/plugins/urvanov-syntax-highlighter/css/min/urvanov_syntax_highlighter.min.css?ver=2.8.37' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='crayon-theme-classic-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/urvanov-syntax-highlighter/themes/classic/classic.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='crayon-font-monaco-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/urvanov-syntax-highlighter/fonts/monaco.css?ver=1732535971' type='text/css' media='all' /> <style id='wp-emoji-styles-inline-css' type='text/css'> img.wp-smiley, img.emoji { display: inline !important; border: none !important; box-shadow: none !important; height: 1em !important; width: 1em !important; margin: 0 0.07em !important; vertical-align: -0.1em !important; background: none !important; padding: 0 !important; } </style> <style id='classic-theme-styles-inline-css' type='text/css'> /*! This file is auto-generated */ .wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none} </style> <style id='global-styles-inline-css' type='text/css'> :root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;} :where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;} :where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;} :root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;} </style> <link data-minify="1" rel='stylesheet' id='dashicons-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-includes/css/dashicons.min.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='wordpress-popular-posts-css-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/wordpress-popular-posts/assets/css/wpp.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='paperback-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/style.css?ver=1732535971' type='text/css' media='all' /> <style id='paperback-style-inline-css' type='text/css'> /* Top Nav Background Color */ .top-navigation, .secondary-navigation ul.sub-menu { background-color: #ffffff; } /* Top Nav Text Color */ .top-navigation, .top-navigation nav a, .top-navigation li ul li a, .drawer-toggle { color: #000000; } .main-navigation:not(.secondary-navigation) ul.menu > li.current-menu-item > a { border-color: #ec1e2c; } /* Header Background Color */ .site-identity { background-color: #ffffff; } /* Header Text Color */ .main-navigation a, .site-title a, .site-description { color: #000000; } /* Accent Color */ .hero-cats a, .post-navigation .nav-label, .entry-cats a { background-color: #ec1e2c; } .page-numbers.current, .page-numbers:hover, #page #infinite-handle button:hover { background-color: #ec1e2c; } /* Footer Background Color */ .site-footer { background-color: #f6f6f6; } /* Footer Text Color */ .site-footer .widget-title, .site-footer a:hover { color: #000000; } .site-footer, .site-footer a { color: rgba( 0, 0, 0, 0.8); } /* Footer Border Color */ .footer-widgets ul li, .footer-widgets + .footer-bottom { border-color: rgba( 0, 0, 0, 0.3); } </style> <link data-minify="1" rel='stylesheet' id='couchbase-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/style.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='root-css-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/root.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='font-awesome-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/inc/fontawesome/css/font-awesome.css?ver=1732535971' type='text/css' media='screen' /> <link data-minify="1" rel='stylesheet' id='heateor_sl_frontend_css-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/heateor-social-login/public/css/heateor-social-login-public.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='thickbox-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-includes/js/thickbox/thickbox.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='heateor_sss_frontend_css-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/sassy-social-share/public/css/sassy-social-share-public.css?ver=1732535971' type='text/css' media='all' /> <style id='heateor_sss_frontend_css-inline-css' type='text/css'> .heateor_sss_button_instagram span.heateor_sss_svg,a.heateor_sss_instagram span.heateor_sss_svg{background:radial-gradient(circle at 30% 107%,#fdf497 0,#fdf497 5%,#fd5949 45%,#d6249f 60%,#285aeb 90%)}.heateor_sss_horizontal_sharing .heateor_sss_svg,.heateor_sss_standard_follow_icons_container .heateor_sss_svg{color:#fff;border-width:0px;border-style:solid;border-color:transparent}.heateor_sss_horizontal_sharing .heateorSssTCBackground{color:#666}.heateor_sss_horizontal_sharing span.heateor_sss_svg:hover,.heateor_sss_standard_follow_icons_container span.heateor_sss_svg:hover{border-color:transparent;}.heateor_sss_vertical_sharing span.heateor_sss_svg,.heateor_sss_floating_follow_icons_container span.heateor_sss_svg{color:#fff;border-width:0px;border-style:solid;border-color:transparent;}.heateor_sss_vertical_sharing .heateorSssTCBackground{color:#666;}.heateor_sss_vertical_sharing span.heateor_sss_svg:hover,.heateor_sss_floating_follow_icons_container span.heateor_sss_svg:hover{border-color:transparent;}@media screen and (max-width:783px) {.heateor_sss_vertical_sharing{display:none!important}}div.heateor_sss_mobile_footer{display:none;}@media screen and (max-width:783px){div.heateor_sss_bottom_sharing .heateorSssTCBackground{background-color:white}div.heateor_sss_bottom_sharing{width:100%!important;left:0!important;}div.heateor_sss_bottom_sharing a{width:25% !important;}div.heateor_sss_bottom_sharing .heateor_sss_svg{width: 100% !important;}div.heateor_sss_bottom_sharing div.heateorSssTotalShareCount{font-size:1em!important;line-height:28px!important}div.heateor_sss_bottom_sharing div.heateorSssTotalShareText{font-size:.7em!important;line-height:0px!important}div.heateor_sss_mobile_footer{display:block;height:40px;}.heateor_sss_bottom_sharing{padding:0!important;display:block!important;width:auto!important;bottom:-2px!important;top: auto!important;}.heateor_sss_bottom_sharing .heateor_sss_square_count{line-height:inherit;}.heateor_sss_bottom_sharing .heateorSssSharingArrow{display:none;}.heateor_sss_bottom_sharing .heateorSssTCBackground{margin-right:1.1em!important}} </style> <link data-minify="1" rel='stylesheet' id='algolia-autocomplete-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/wp-search-with-algolia/css/algolia-autocomplete.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='header-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/header.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='header-ipad-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/header-ipad.css?ver=1732535971' type='text/css' media='only screen and (min-width: 1025px)' /> <link data-minify="1" rel='stylesheet' id='common-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/common.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='paperback-fonts-gotham-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/hco_fonts/hco_fonts.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='posts-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/posts.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='posts-ipad-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/posts-ipad.css?ver=1732535971' type='text/css' media='only screen and (min-width: 768px)' /> <link data-minify="1" rel='stylesheet' id='promotion-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/promotion-banner.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='footer-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/footer.css?ver=1732535971' type='text/css' media='all' /> <link data-minify="1" rel='stylesheet' id='footer-ipad-style-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/css/footer-ipad.css?ver=1732535971' type='text/css' media='only screen and (min-width: 768px)' /> <script type="text/javascript" src="https://www.couchbase.com/blog/wp-content/themes/couchbase/js/jquery.min.js?ver=3.3.5" id="jquery-js"></script> <script type="text/javascript" id="urvanov_syntax_highlighter_js-js-extra"> /* <![CDATA[ */ var UrvanovSyntaxHighlighterSyntaxSettings = {"version":"2.8.37","is_admin":"0","ajaxurl":"https:\/\/www.couchbase.com\/blog\/wp-admin\/admin-ajax.php","prefix":"urvanov-syntax-highlighter-","setting":"urvanov-syntax-highlighter-setting","selected":"urvanov-syntax-highlighter-setting-selected","changed":"urvanov-syntax-highlighter-setting-changed","special":"urvanov-syntax-highlighter-setting-special","orig_value":"data-orig-value","debug":""}; var UrvanovSyntaxHighlighterSyntaxStrings = {"copy":"Copied to the clipboard","minimize":"Click To Expand Code"}; /* ]]> */ </script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/plugins/urvanov-syntax-highlighter/js/min/urvanov_syntax_highlighter.min.js?ver=2.8.37" id="urvanov_syntax_highlighter_js-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/terminus-chat.js?ver=1732535971" id="couchbase-terminus-chatbot-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/paperback.js?ver=1732535971" id="couchbase-paperback-js-js"></script> <link rel="https://api.w.org/" href="https://www.couchbase.com/blog/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://www.couchbase.com/blog/wp-json/wp/v2/posts/14562" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://www.couchbase.com/blog/xmlrpc.php?rsd" /> <link rel='shortlink' href='https://www.couchbase.com/blog/?p=14562' /> <link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://www.couchbase.com/blog/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F" /> <link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://www.couchbase.com/blog/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F&format=xml" /> <!-- Google Tag Manager for WordPress by gtm4wp.com --> <!-- GTM Container placement set to footer --> <script data-cfasync="false" data-pagespeed-no-defer type="text/javascript"> var dataLayer_content = {"pageTitle":"Recursive Query Processing in SQL++ (N1QL) Function","pagePostType":"post","pagePostType2":"single-post","pageCategory":["couchbase-server","data-modeling","javascript","n1ql-query"],"pageAttributes":["query-language","recursive-queries","udf"],"pagePostAuthorID":84423,"pagePostAuthor":"Gaurav Jayaraj - Intern, Couchbase R&D","pagePostDate":"June 23, 2023","pagePostDateYear":2023,"pagePostDateMonth":6,"pagePostDateDay":23,"pagePostDateDayName":"Friday","pagePostDateHour":13,"pagePostDateMinute":15,"pagePostDateIso":"2023-06-23T13:15:52-07:00","pagePostDateUnix":1687526152,"postCountOnPage":1,"postCountTotal":1,"postID":14562,"postFormat":"standard"}; dataLayer.push( dataLayer_content ); </script> <script type="rocketlazyloadscript" data-cfasync="false"> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//metrics.couchbase.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-MVPNN2'); </script> <!-- End Google Tag Manager for WordPress by gtm4wp.com --> <style id="wpp-loading-animation-styles">@-webkit-keyframes bgslide{from{background-position-x:0}to{background-position-x:-200%}}@keyframes bgslide{from{background-position-x:0}to{background-position-x:-200%}}.wpp-widget-block-placeholder,.wpp-shortcode-placeholder{margin:0 auto;width:60px;height:3px;background:#dd3737;background:linear-gradient(90deg,#dd3737 0%,#571313 10%,#dd3737 100%);background-size:200% auto;border-radius:3px;-webkit-animation:bgslide 1s infinite linear;animation:bgslide 1s infinite linear}</style> <style type="text/css"> .site-identity { padding: 2% 0; } .single .hero-posts .with-featured-image { padding-top: 26%; } </style> <link rel="icon" href="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/10/couchbase-favicon.svg" sizes="32x32" /> <link rel="icon" href="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/10/couchbase-favicon.svg" sizes="192x192" /> <link rel="apple-touch-icon" href="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/10/couchbase-favicon.svg" /> <meta name="msapplication-TileImage" content="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/10/couchbase-favicon.svg" /> <style type="text/css" id="wp-custom-css"> @media all and (max-width: 1200px) { .algolia-autocomplete { display: none !important; } } </style> <style type="text/css">/** Mega Menu CSS: disabled **/</style> <!-- OneTrust Cookies Consent Notice start for couchbase.com --> <script type="rocketlazyloadscript" data-rocket-src="https://cdn.cookielaw.org/scripttemplates/otSDKStub.js" data-rocket-type="text/javascript" charset="UTF-8" data-domain-script="748511ff-10bf-44bf-88b8-36382e5b5fd9"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript"> function OptanonWrapper() {} </script> <!-- OneTrust Cookies Consent Notice end for couchbase.com --></head> <body class="post-template-default single single-post postid-14562 single-format-standard mega-menu-cb-header-menu has-sidebar two-column group-blog"> <header data-rocket-location-hash="9fcecfaaa44ad8e28dbd90e4c1fb5574" id="masthead" class="site-header" role="banner"> <div data-rocket-location-hash="e7d8a912baa9a7189e4a89d4eb70ce8c" class="container flex"> <div data-rocket-location-hash="f088df60018cae7995f97c076547015a" class="brand_logo_wrap"> <a href="https://www.couchbase.com/"> <img src="https://www.couchbase.com/blog/wp-content/themes/couchbase/images/Logo-2000.svg" width="203" height="46" alt="Couchbase Website"> </a> </div> <div data-rocket-location-hash="e57c28d77d16894c0097428953c90bc1" class="mega-menu-toggle ipad-menu" id="megaToggle"></div> <nav class="menu-container"> <div id="mega-menu-wrap-cb-header-menu" class="mega-menu-wrap"><div class="mega-menu-toggle"><div class="mega-toggle-blocks-left"></div><div class="mega-toggle-blocks-center"></div><div class="mega-toggle-blocks-right"><div class='mega-toggle-block mega-menu-toggle-animated-block mega-toggle-block-0' id='mega-toggle-block-0'><button aria-label="Toggle Menu" class="mega-toggle-animated mega-toggle-animated-slider" type="button" aria-expanded="false"> <span class="mega-toggle-animated-box"> <span class="mega-toggle-animated-inner"></span> </span> </button></div></div></div><ul id="mega-menu-cb-header-menu" class="mega-menu max-mega-menu mega-menu-horizontal mega-no-js" data-event="hover" data-effect="disabled" data-effect-speed="200" data-effect-mobile="disabled" data-effect-speed-mobile="0" data-mobile-force-width="false" data-second-click="go" data-document-click="collapse" data-vertical-behaviour="standard" data-breakpoint="1024" data-unbind="true" data-mobile-state="collapse_all" data-mobile-direction="vertical" data-hover-intent-timeout="300" data-hover-intent-interval="100"><li class='mega-products-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-item-has-children mega-menu-megamenu mega-align-bottom-left mega-menu-grid mega-menu-item-13438 products-menu' id='mega-menu-item-13438'><a class="mega-menu-link" href="#" aria-expanded="false" tabindex="0">Products<span class="mega-indicator"></span></a> <ul class="mega-sub-menu"> <li class='mega-menu-row mega-row-products-menu row-products-menu' id='mega-menu-13438-0'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-grid-products-menu mega-menu-columns-1-of-2 grid-products-menu' id='mega-menu-13438-0-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-29' id='mega-menu-item-nav_menu-29'><h4 class="mega-block-title">Platform</h4><div class="menu-platform-container"><ul id="menu-platform" class="menu"><li id="menu-item-15750" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15750"><a href="/products/capella/">Couchbase Capella<span>Database-as-a-Service</span></a></li> </ul></div></li><li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-30' id='mega-menu-item-nav_menu-30'><h4 class="mega-block-title">Self-Managed</h4><div class="menu-self-managed-container"><ul id="menu-self-managed" class="menu"><li id="menu-item-15755" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15755"><a href="/products/server/">Couchbase Server<span>On-prem, multicloud, community</span></a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-grid-products-menu mega-menu-columns-1-of-2 grid-products-menu' id='mega-menu-13438-0-1'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-27' id='mega-menu-item-nav_menu-27'><h4 class="mega-block-title">Services</h4><div class="menu-services-container"><ul id="menu-services" class="menu"><li id="menu-item-15751" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15751"><a href="/products/vector-search/">Artificial Intelligence <span>GenAI, coding assistance, RAG</span></a></li> <li id="menu-item-15752" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15752"><a href="/products/full-text-search/">Search <span>Full-text, hybrid, geospatial, vector</span></a></li> <li id="menu-item-15753" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15753"><a href="/products/mobile/">Mobile<span>Embedded NoSQL, cloud to edge sync, offline-first</span></a></li> <li id="menu-item-15754" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15754"><a href="/products/analytics/">Columnar Analytics<span>Real-time, multisource analytics</span></a></li> </ul></div></li><li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-28' id='mega-menu-item-nav_menu-28'><h4 class="mega-block-title">Capabilities</h4><div class="menu-capabilities-container"><ul id="menu-capabilities" class="menu"><li id="menu-item-15756" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15756"><a href="/developers/architecture/">In-memory Architecture<span>Speed, scale, availability</span></a></li> <li id="menu-item-15757" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15757"><a href="/developers/">Build Flexible Apps<span>JSON, SQL++, multipurpose</span></a></li> <li id="menu-item-15758" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15758"><a href="/products/operator/">Cloud Automation<span>Kubernetes Operator</span></a></li> <li id="menu-item-15759" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15759"><a href="/developers/sdks/">Dev Tools<span>SDKs, integrations, Capella iQ</span></a></li> </ul></div></li> </ul> </li> </ul> </li><li class='mega-menu-row mega-bg-peach bg-peach' id='mega-menu-13438-1'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-menu-columns-1-of-1' id='mega-menu-13438-1-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_custom_html mega-menu-item-custom_html-16' id='mega-menu-item-custom_html-16'><h4 class="mega-block-title">Why Couchbase?</h4><div class="textwidget custom-html-widget"><div class='menu-card'> <p>Developers and enterprises choose Couchbase for their mission-critical applications.</p> <a href='/why-couchbase/' class='cta-btn bg-black text-white'>See Why</a> </div> <div class='menu-card before-border'> <h4 class="mega-inner-title">Vector Search</h4> <p>Vector search delivers nearest-neighbor results, without needing a direct match.</p> <a href='/products/vector-search/' class='cta-btn bg-black text-white'>Learn More</a> </div></div></li> </ul> </li> </ul> </li></ul> </li><li class='mega-solutions-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-item-has-children mega-menu-megamenu mega-align-bottom-left mega-menu-grid mega-menu-item-13439 solutions-menu' id='mega-menu-item-13439'><a class="mega-menu-link" href="#" aria-expanded="false" tabindex="0">Solutions<span class="mega-indicator"></span></a> <ul class="mega-sub-menu"> <li class='mega-menu-row' id='mega-menu-13439-0'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-w-36 mega-menu-columns-4-of-12 w-36' id='mega-menu-13439-0-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-31' id='mega-menu-item-nav_menu-31'><h4 class="mega-block-title">By Use Case</h4><div class="menu-by-use-case-container"><ul id="menu-by-use-case" class="menu"><li id="menu-item-15760" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15760"><a href="/use-cases/artificial-intelligence/">Artificial Intelligence</a></li> <li id="menu-item-15761" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15761"><a href="/use-cases/session-management/">Caching and Session Management</a></li> <li id="menu-item-15762" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15762"><a href="/use-cases/product-catalog/">Adaptive Product Catalog</a></li> <li id="menu-item-15763" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15763"><a href="/use-cases/smart-personalization/">Smart Personalization & Profiles</a></li> <li id="menu-item-15764" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15764"><a href="/use-cases/field-service/">Adaptive Field Services</a></li> <li id="menu-item-15765" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15765"><a href="/use-cases/real-time-analytics/">Real-Time Analytics for AI</a></li> <li id="menu-item-15766" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-15766"><a href="/use-cases/#usecaseIndustry_1">See all use cases</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-28 mega-menu-columns-4-of-12 w-28' id='mega-menu-13439-0-1'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-32' id='mega-menu-item-nav_menu-32'><h4 class="mega-block-title">By Industry</h4><div class="menu-by-industry-container"><ul id="menu-by-industry" class="menu"><li id="menu-item-13452" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13452"><a href="/use-cases/energy-and-utilities/">Energy & Utilities</a></li> <li id="menu-item-13453" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13453"><a href="/use-cases/gaming/">Gaming</a></li> <li id="menu-item-13454" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13454"><a href="/use-cases/healthcare/">Healthcare</a></li> <li id="menu-item-13455" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13455"><a href="/use-cases/media-and-entertainment/">Entertainment</a></li> <li id="menu-item-13456" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13456"><a href="/use-cases/retail-and-ecommerce/">Retail</a></li> <li id="menu-item-15024" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15024"><a href="/use-cases/travel-and-hospitality/">Travel & Hospitality</a></li> <li id="menu-item-13457" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-13457"><a href="/use-cases/#usecaseIndustry_2">See all industries</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-36 mega-menu-columns-4-of-12 w-36' id='mega-menu-13439-0-2'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-33' id='mega-menu-item-nav_menu-33'><h4 class="mega-block-title">By Application Need</h4><div class="menu-by-application-need-container"><ul id="menu-by-application-need" class="menu"><li id="menu-item-13458" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13458"><a href="/use-cases/application-performance/">Application Performance</a></li> <li id="menu-item-13459" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13459"><a href="/use-cases/distributed-workloads/">Distributed Workloads</a></li> <li id="menu-item-13460" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13460"><a href="/use-cases/application-flexibility/">Application Flexibility</a></li> <li id="menu-item-13461" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13461"><a href="/use-cases/edge-computing/">Mobile, IoT, & Edge</a></li> <li id="menu-item-13462" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13462"><a href="/use-cases/developer-productivity/">Developer Productivity</a></li> <li id="menu-item-15023" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15023"><a href="/use-cases/operational-cost-reduction/">High Cost Of Operations</a></li> <li id="menu-item-13463" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-13463"><a href="/use-cases/#usecaseIndustry_3">See all application needs</a></li> </ul></div></li> </ul> </li> </ul> </li></ul> </li><li class='mega-developers-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-item-has-children mega-menu-megamenu mega-align-bottom-left mega-menu-grid mega-menu-item-14175 developers-menu' id='mega-menu-item-14175'><a class="mega-menu-link" href="#" aria-expanded="false" tabindex="0">Developers<span class="mega-indicator"></span></a> <ul class="mega-sub-menu"> <li class='mega-menu-row' id='mega-menu-14175-0'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-w-30 mega-menu-columns-4-of-12 w-30' id='mega-menu-14175-0-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-35' id='mega-menu-item-nav_menu-35'><h4 class="mega-block-title">Popular Docs</h4><div class="menu-popular-docs-container"><ul id="menu-popular-docs" class="menu"><li id="menu-item-13485" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13485"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/cloud/index.html">Capella Overview</a></li> <li id="menu-item-13486" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13486"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/server/current/introduction/why-couchbase.html">Server Overview</a></li> <li id="menu-item-13487" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13487"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/home/mobile.html">Mobile & Edge Overview</a></li> <li id="menu-item-13488" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13488"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/home/sdk.html">Connecting Apps (SDKs)</a></li> <li id="menu-item-13489" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13489"><a target="_blank" rel="noopener" href="https://developer.couchbase.com/tutorials">Tutorials & Samples</a></li> <li id="menu-item-13490" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-13490"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/home/index.html">Docs Home</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-28 mega-menu-columns-4-of-12 w-28' id='mega-menu-14175-0-1'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-34' id='mega-menu-item-nav_menu-34'><h4 class="mega-block-title">By Developer Role</h4><div class="menu-by-developer-role-container"><ul id="menu-by-developer-role" class="menu"><li id="menu-item-15012" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15012"><a href="https://www.couchbase.com/developers/backend/">Backend</a></li> <li id="menu-item-15013" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15013"><a href="https://www.couchbase.com/developers/full-stack/">Full Stack</a></li> <li id="menu-item-15014" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15014"><a href="https://www.couchbase.com/developers/mobile/">Mobile</a></li> <li id="menu-item-15015" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15015"><a href="https://www.couchbase.com/developers/devops-dbas/">Ops / DBA</a></li> <li id="menu-item-15025" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-15025"><a href="https://www.couchbase.com/developers/">Developers Home</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-custom-width mega-bg-peach mega-menu-columns-4-of-12 custom-width bg-peach' id='mega-menu-14175-0-2'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_custom_html mega-menu-item-custom_html-17' id='mega-menu-item-custom_html-17'><h4 class="mega-block-title">Capella Playground</h4><div class="textwidget custom-html-widget"><div class='menu-card'> <a class='menu-banner' href='https://cloud.couchbase.com/sign-up'><img loading='lazy' src='https://www.couchbase.com/wp-content/uploads/sites/3/2022/10/capella-free-trial-01.png' alt=''> </a> <h6 class='mega-inner-title'> Start A Free Capella Trial </h6> <p> Try the Couchbase Capella Playground. </p> <a href='https://cloud.couchbase.com/sign-up' class='cta-btn bg-black text-white' target='_blank' rel="noopener">Sign Up</a> </div></div></li> </ul> </li> </ul> </li></ul> </li><li class='mega-resources-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-item-has-children mega-menu-megamenu mega-align-bottom-left mega-menu-grid mega-menu-item-13441 resources-menu' id='mega-menu-item-13441'><a class="mega-menu-link" href="#" aria-expanded="false" tabindex="0">Resources<span class="mega-indicator"></span></a> <ul class="mega-sub-menu"> <li class='mega-menu-row' id='mega-menu-13441-0'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-w-36 mega-menu-columns-4-of-12 w-36' id='mega-menu-13441-0-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-36' id='mega-menu-item-nav_menu-36'><h4 class="mega-block-title">Resource Center</h4><div class="menu-resource-center-container"><ul id="menu-resource-center" class="menu"><li id="menu-item-15016" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-15016"><a target="_blank" rel="noopener" href="https://www.couchbase.com/blog/">Blogs</a></li> <li id="menu-item-13514" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13514"><a href="https://www.couchbase.com/resources/webcasts-and-events/">Webcasts & Events</a></li> <li id="menu-item-13513" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13513"><a href="https://www.couchbase.com/resources/?query=&content=Videos%20and%20Presentations&page=1">Videos & Presentations</a></li> <li id="menu-item-13515" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13515"><a href="https://www.couchbase.com/resources/nosql-whitepapers/">Whitepapers</a></li> <li id="menu-item-13516" class="active-link menu-item menu-item-type-custom menu-item-object-custom menu-item-13516"><a href="https://www.couchbase.com/resources/">See all resources</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-28 mega-menu-columns-4-of-12 w-28' id='mega-menu-13441-0-1'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-37' id='mega-menu-item-nav_menu-37'><h4 class="mega-block-title">Education</h4><div class="menu-education-container"><ul id="menu-education" class="menu"><li id="menu-item-13473" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13473"><a href="https://www.couchbase.com/academy/">Academy</a></li> <li id="menu-item-13474" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13474"><a href="https://www.couchbase.com/academy/certification/">Certification</a></li> <li id="menu-item-13476" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13476"><a target="_blank" rel="noopener" href="https://www.couchbase.com/forums/">Forums</a></li> <li id="menu-item-13477" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13477"><a target="_blank" rel="noopener" href="https://support.couchbase.com/hc/en-us/">Support Login</a></li> <li id="menu-item-15017" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15017"><a href="https://docs.couchbase.com/">Documentation</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-36 mega-menu-columns-4-of-12 w-36' id='mega-menu-13441-0-2'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-41' id='mega-menu-item-nav_menu-41'><h4 class="mega-block-title">Compare</h4><div class="menu-compare-container"><ul id="menu-compare" class="menu"><li id="menu-item-16598" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16598"><a href="/comparing-couchbase-vs-mongodb/">Couchbase vs. MongoDB</a></li> <li id="menu-item-16599" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16599"><a href="/comparing-couchbase-vs-oracle/">Couchbase vs. Oracle</a></li> <li id="menu-item-16600" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16600"><a href="/comparing-couchbase-vs-dynamodb/">Couchbase vs. DynamoDB</a></li> <li id="menu-item-16601" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16601"><a href="/mongodb-redis/">Couchbase vs. Redis</a></li> <li id="menu-item-16602" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16602"><a href="/nosql-database-cloud-comparison/">NoSQL Cloud Comparison</a></li> </ul></div></li> </ul> </li> </ul> </li></ul> </li><li class='mega-company-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-menu-item-has-children mega-menu-megamenu mega-align-bottom-left mega-menu-grid mega-menu-item-13442 company-menu' id='mega-menu-item-13442'><a class="mega-menu-link" href="#" aria-expanded="false" tabindex="0">Company<span class="mega-indicator"></span></a> <ul class="mega-sub-menu"> <li class='mega-menu-row' id='mega-menu-13442-0'> <ul class="mega-sub-menu"> <li class='mega-menu-column mega-w-20 mega-pr-10 mega-menu-columns-3-of-12 w-20 pr-10' id='mega-menu-13442-0-0'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-38' id='mega-menu-item-nav_menu-38'><h4 class="mega-block-title">About</h4><div class="menu-about-container"><ul id="menu-about" class="menu"><li id="menu-item-13446" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13446"><a href="https://www.couchbase.com/about/">About Us</a></li> <li id="menu-item-13447" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13447"><a href="https://www.couchbase.com/leadership/">Leadership</a></li> <li id="menu-item-13448" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13448"><a href="https://www.couchbase.com/customers/">Customers</a></li> <li id="menu-item-15021" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15021"><a href="https://investors.couchbase.com/">Investors</a></li> <li id="menu-item-15022" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-15022"><a href="https://www.couchbase.com/blog/">Blog</a></li> <li id="menu-item-13450" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13450"><a href="https://www.couchbase.com/news-and-press-releases/">Newsroom</a></li> <li id="menu-item-13451" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13451"><a href="/careers/">Careers</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-20 mega-pl-20 mega-pr-10 mega-menu-columns-3-of-12 w-20 pl-20 pr-10' id='mega-menu-13442-0-1'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-39' id='mega-menu-item-nav_menu-39'><h4 class="mega-block-title">Partnerships</h4><div class="menu-partnerships-container"><ul id="menu-partnerships" class="menu"><li id="menu-item-15018" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15018"><a href="/partners/find-a-partner/">Find a Partner</a></li> <li id="menu-item-15019" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15019"><a href="/partners/partner-with-couchbase/">Become a Partner</a></li> <li id="menu-item-15020" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-15020"><a href="/register-a-deal/">Register a Deal</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-w-26 mega-pl-20 mega-menu-columns-3-of-12 w-26 pl-20' id='mega-menu-13442-0-2'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_nav_menu mega-menu-item-nav_menu-40' id='mega-menu-item-nav_menu-40'><h4 class="mega-block-title">Our Services</h4><div class="menu-our-services-container"><ul id="menu-our-services" class="menu"><li id="menu-item-13482" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13482"><a href="https://www.couchbase.com/professional-services/">Professional Services</a></li> <li id="menu-item-13484" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-13484"><a target="_blank" rel="noopener" href="https://support.couchbase.com/hc/en-us/">Enterprise Support</a></li> </ul></div></li> </ul> </li><li class='mega-menu-column mega-bg-peach mega-cp-custom-width mega-menu-columns-3-of-12 bg-peach cp-custom-width' id='mega-menu-13442-0-3'> <ul class="mega-sub-menu"> <li class='mega-menu-item mega-menu-item-type-widget widget_custom_html mega-menu-item-custom_html-19' id='mega-menu-item-custom_html-19'><h4 class="mega-block-title">Partners: Register a Deal</h4><div class="textwidget custom-html-widget"><div class='menu-card'> <h6 class='mega-inner-title'> Ready to register a deal with Couchbase? </h6> <p> Let us know your partner details and more about the prospect you are registering. </p> <a href='https://www.couchbase.com/register-a-deal/' class='cta-btn bg-black text-white'>Start here</a> </div> <div class='menu-card before-border'> <h6 class='mega-inner-title'> Marriott </h6> <p> Marriott chose Couchbase over MongoDB and Cassandra for their reliable personalized customer experience. </p> <a href='https://www.couchbase.com/customers/marriott/' class='cta-btn bg-black text-white'>Learn more</a> </div></div></li> </ul> </li> </ul> </li></ul> </li><li class='mega-action-item mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-align-bottom-left mega-menu-flyout mega-menu-item-13445 action-item' id='mega-menu-item-13445'><a class="mega-menu-link" href="https://www.couchbase.com/pricing/" tabindex="0">Pricing</a></li><li class='mega-free-trial mega-blue-btn mega-right-side-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-align-bottom-left mega-menu-flyout mega-menu-item-13443 free-trial blue-btn right-side-menu' id='mega-menu-item-13443'><a class="mega-menu-link" href="https://www.couchbase.com/downloads/" tabindex="0">Try Free</a></li><li class='mega-sign-in-link mega-right-side-menu mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-align-bottom-left mega-menu-flyout mega-menu-item-13444 sign-in-link right-side-menu' id='mega-menu-item-13444'><a target="_blank" class="mega-menu-link" href="https://cloud.couchbase.com/" tabindex="0">Sign In</a></li><li class='mega-right-side-menu mega-search-icon mega-menu-item mega-menu-item-type-custom mega-menu-item-object-custom mega-align-bottom-left mega-menu-flyout mega-menu-item-13971 right-side-menu search-icon' id='mega-menu-item-13971'><a class="mega-menu-link" href="/search/" tabindex="0">search</a></li></ul></div> <div class="blog-main-menu drawer-menu-explore"> <nav id="site-navigation" class="blog-main-navigation " role="navigation"> <div class="menu-md-wrap"> <div class="menu-primary-container"><ul id="menu-primary" class="blog-menu"><li id="menu-item-5792" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-5792"><a href="https://www.couchbase.com/blog/">Blog</a></li> <li id="menu-item-1086" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-1086"><a href="javascript:void(0);">Browse by Topic</a> <ul class="sub-menu"> <li id="menu-item-12007" class="menu-heading menu-heading-red menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12007"><a href="javascript:void(0);">Topics</a> <ul class="sub-menu"> <li id="menu-item-12008" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12008"><a href="/blog/category/application-design/?ref=blog-menu">Application Design</a></li> <li id="menu-item-12009" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12009"><a href="/blog/category/data-modeling/?ref=blog-menu">Data Modeling</a></li> <li id="menu-item-12010" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12010"><a href="/blog/category/couchbase-architecture/?ref=blog-menu">Architecture</a></li> <li id="menu-item-12011" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12011"><a href="/blog/category/performance/?ref=blog-menu">Performance</a></li> <li id="menu-item-16036" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-16036"><a href="/blog/tag/artificial-intelligence/?ref=blog-menu">Artificial Intelligence</a></li> <li id="menu-item-12013" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12013"><a href="/blog/category/security/?ref=blog-menu">Security</a></li> <li id="menu-item-12012" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12012"><a href="/blog/category/best-practices-and-tutorials/?ref=blog-menu">Best Practices & Tutorials</a></li> </ul> </li> </ul> </li> <li id="menu-item-12014" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12014"><a href="javascript:void(0);">Browse by Specialization</a> <ul class="sub-menu"> <li id="menu-item-12015" class="menu-heading menu-heading-red menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12015"><a href="javascript:void(0);">Specializations</a> <ul class="sub-menu"> <li id="menu-item-12016" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12016"><a href="javascript:void(0);">Products</a> <ul class="sub-menu"> <li id="menu-item-12017" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12017"><a href="/blog/category/cloud/?ref=blog-menu">Capella</a></li> <li id="menu-item-12018" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12018"><a href="/blog/category/couchbase-server/?ref=blog-menu">Server</a></li> <li id="menu-item-12019" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12019"><a href="/blog/category/couchbase-autonomous-operator/?ref=blog-menu">Autonomous Operator</a></li> <li id="menu-item-12020" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12020"><a href="/blog/category/couchbase-mobile/?ref=blog-menu">Mobile</a></li> <li id="menu-item-12021" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12021"><a href="/blog/category/sync-gateway/?ref=blog-menu">Sync Gateway</a></li> <li id="menu-item-12022" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12022"><a href="/blog/category/couchbase-lite/?ref=blog-menu">Lite</a></li> </ul> </li> <li id="menu-item-12023" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12023"><a href="javascript:void(0);">SDKs</a> <ul class="sub-menu"> <li id="menu-item-12024" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12024"><a href="/blog/category/java/?ref=blog-menu">Java</a></li> <li id="menu-item-12025" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12025"><a href="/blog/category/dotnet/?ref=blog-menu">.NET</a></li> <li id="menu-item-12026" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12026"><a href="/blog/category/scala/?ref=blog-menu">Scala</a></li> <li id="menu-item-12027" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12027"><a href="/blog/category/ruby/?ref=blog-menu">Ruby</a></li> <li id="menu-item-12028" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12028"><a href="/blog/category/node-js/?ref=blog-menu">Node.js</a></li> <li id="menu-item-12029" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12029"><a href="/blog/category/android/?ref=blog-menu">Android</a></li> <li id="menu-item-12030" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12030"><a href="/blog/category/python/?ref=blog-menu">Python</a></li> <li id="menu-item-12031" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12031"><a href="/blog/category/php/?ref=blog-menu">PHP</a></li> <li id="menu-item-12032" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12032"><a href="/blog/category/swift/?ref=blog-menu">Swift</a></li> <li id="menu-item-12033" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12033"><a href="/blog/category/golang/?ref=blog-menu">GoLang</a></li> <li id="menu-item-12034" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12034"><a href="/blog/category/objective-c/?ref=blog-menu">Objective-C</a></li> </ul> </li> <li id="menu-item-12035" class="disable-link menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-12035"><a href="javascript:void(0);">Capabilities</a> <ul class="sub-menu"> <li id="menu-item-12036" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12036"><a href="/blog/category/n1ql-query/?ref=blog-menu">SQL++ (N1QL)</a></li> <li id="menu-item-12037" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12037"><a href="/blog/category/multi-dimensional-scaling/?ref=blog-menu">Multi-Dimensional Scaling</a></li> <li id="menu-item-12038" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12038"><a href="/blog/category/xdcr/?ref=blog-menu">XDCR</a></li> <li id="menu-item-12039" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12039"><a href="/blog/tag/caching/?ref=blog-menu">Caching</a></li> <li id="menu-item-12040" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12040"><a href="/blog/category/full-text-search/?ref=blog-menu">Full-Text Search</a></li> <li id="menu-item-12041" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12041"><a href="/blog/category/analytics/?ref=blog-menu">Analytics</a></li> <li id="menu-item-12042" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12042"><a href="/blog/category/indexing/?ref=blog-menu">Indexing</a></li> <li id="menu-item-12043" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12043"><a href="/blog/category/eventing/?ref=blog-menu">Eventing</a></li> <li id="menu-item-12044" class="hyperlink-effect menu-item menu-item-type-custom menu-item-object-custom menu-item-12044"><a href="/blog/category/backup/?ref=blog-menu">Backup</a></li> </ul> </li> </ul> </li> </ul> </li> </ul></div> </div> <div class="top-navigation-right"> <!-- --> <div id="searchbox" class="nav-searchbox"></div> <a class="blog-login-btn" href="/blog/wp-login.php" title="Blog Sign In" rel="home">Blog Sign In ></a> </div> </nav> </div> </nav> </div> </header> <div data-rocket-location-hash="74877e57db162c3f704265c4c1fc9723" class="nav-overlay"></div> <div data-rocket-location-hash="e80a859663525ad682af03bf0364c4ae" class="algolia-hits" id="hits-block"> <h6 class="algolia-post-title">All Posts</h6> <div data-rocket-location-hash="aa61f5a26aafa8af2a3c82b3251dc7a4" id="hits"></div> <button id="see-all-button" class="see-all-button cta-btn bg-black text-white">See All Results</button> </div> <div data-rocket-location-hash="1d0175788614cfc0ce4ec06cb0ca36be" class="hero-wrapper"> <div data-rocket-location-hash="d6f4ae76a9934a997115d4dbc5a35227" class="hero-posts"> <div data-rocket-location-hash="f587cf50e6ce0b5b431f5f9d598b0a32" id="post-14562" class="with-featured-image hero-post post-14562 post type-post status-publish format-standard has-post-thumbnail hentry category-couchbase-server category-data-modeling category-javascript category-n1ql-query tag-query-language tag-recursive-queries tag-udf"> <!-- Get the hero background image --> <div class="site-header-bg-wrap"> <div class="header-opacity"> <div class="header-gradient"></div> <div class="site-header-bg background-effect" style="background-image: url(https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/remy-penet-zaM9LhySx_0-unsplash-scaled.jpg); opacity: 0.5;"></div> </div> </div><!-- .site-header-bg-wrap --> <div class="container hero-container"> <!-- Hero title --> <div class="hero-text"> <h1 class="entry-title">Recursive Query Processing in SQL++ (N1QL)</h1> <div class="hero-date"> <ul> <li> <!-- Create an avatar link --> <a class="author-profile-avatar" href="https://www.couchbase.com/blog/author/gauravjayaraj/" title="Posts by Gaurav Jayaraj - Intern, Couchbase R&D"> <img alt='' src='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=65&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=130&d=mm&r=g 2x' class='avatar avatar-65 photo' height='65' width='65' decoding='async'/> </a> </li> <li> <div class="auth_detail_wrp"> <!-- Create an author post link --> <a class="auth_name" href="https://www.couchbase.com/blog/author/gauravjayaraj/"> Gaurav Jayaraj - Intern, Couchbase R&D </a> </div> <div class="date_blog"> <span class="hero-date-span">June 23, 2023</span> </div> </li> </ul> </div> </div><!-- .photo-overlay --> </div><!-- .container --> </div> </div><!-- .hero-posts --> </div><!-- .hero-wrapper --> <div data-rocket-location-hash="71b719af51dc65717bbb466f3afa034d" id="page" class="hfeed site container"> <div data-rocket-location-hash="ab7635cdc6228f2213d248cd4cde9ab1" id="content" class="site-content"> <div data-rocket-location-hash="495936cbeb6374bace73b1518178ba49" id="primary" class="content-area"> <main id="main" class="site-main" role="main"> <article id="post-14562" class="post full-post post-14562 type-post status-publish format-standard has-post-thumbnail hentry category-couchbase-server category-data-modeling category-javascript category-n1ql-query tag-query-language tag-recursive-queries tag-udf"> <div class="entry-content"> <p><span style="font-weight: 400">It is extremely likely that you have come across issues with </span><b>hierarchical lookups or graph traversal</b><span style="font-weight: 400"> in your application as a developer who handles real-world use cases. And, for obvious reasons, you prefer solving them at the </span><b>database layer and not at the client-side</b><span style="font-weight: 400">.</span></p> <h2><span style="font-weight: 400">What are hierarchical lookups?</span></h2> <p><span style="font-weight: 400">Hierarchical lookup refers to the process of searching and retrieving data from a hierarchical structure, such as a </span><b>tree or a parent-child relationship</b><span style="font-weight: 400">. It involves navigating through the levels or layers of the hierarchy to locate specific data elements or related information, for example, organizational charts, file systems, and category trees.</span></p> <p><span style="font-weight: 400">Graphs are basically trees that may have cycles, so additionally, we could also cover use cases like path finding, etc provided we have additional configurations to deal with cycles.</span></p> <p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-14566" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_124236084.png" alt="hierachical lookups" width="1019" height="679" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124236084.png 1019w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124236084-300x200.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124236084-768x512.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124236084-400x267.png 400w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124236084-450x300.png 450w" sizes="(max-width: 1019px) 100vw, 1019px" /></p> <p><span style="font-weight: 400">Consider an example using an employee collection with a hierarchical structure. Employees are organized in a manager-subordinate relationship. We’ll perform operations on this employee hierarchy using Couchbase and JavaScript UDFs to demonstrate the solution.</span></p> <p><span style="font-weight: 400">Going from the </span><i><span style="font-weight: 400">Employee Collection </span></i><span style="font-weight: 400">we can retrieve:</span></p> <p><span style="font-weight: 400">i) generic employee-level:</span></p> <p><img decoding="async" class="alignnone size-large wp-image-14567" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_124344227-1024x555.png" alt="" width="900" height="488" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124344227-1024x555.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124344227-300x163.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124344227-768x416.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124344227.png 1238w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p><span style="font-weight: 400">ii) hierarchy for each employee:</span></p> <p><img decoding="async" class="alignnone size-large wp-image-14568" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_124413697-1024x379.png" alt="" width="900" height="333" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124413697-1024x379.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124413697-300x111.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124413697-768x284.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124413697.png 1296w" sizes="(max-width: 900px) 100vw, 900px" /></p> <h2><span style="font-weight: 400">What this blog covers</span></h2> <p><span style="font-weight: 400">You really like the </span><b>flexibility</b><span style="font-weight: 400"> of NoSQL databases, and your underlying data model is </span><b>JSON, </b><span style="font-weight: 400">which is why you have chosen Couchbase for your database needs (great choice, btw :-) ).</span></p> <p><span style="font-weight: 400">Now that you have Couchbase as your database, you want to solve the above mentioned problem. After doing some research in the </span><a href="https://www.couchbase.com/sqlplusplus/"><span style="font-weight: 400">SQL++</span></a><span style="font-weight: 400"> Language Reference docs</span><span style="font-weight: 400"> you have come to the conclusion that there is no </span><i><span style="font-weight: 400">Statement </span></i><span style="font-weight: 400">or </span><i><span style="font-weight: 400">Function </span></i><span style="font-weight: 400">support in SQL++ to solve our problem, like the </span><a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/?_ga=2.234064094.1723037650.1675387315-1783168968.1675058199#-graphlookup--aggregation-"><span style="font-weight: 400">graphLookup</span></a><span style="font-weight: 400"> API in MongoDB or </span><a href="https://docs.snowflake.com/en/user-guide/queries-cte#recursive-ctes-and-hierarchical-data"><span style="font-weight: 400">recursive CTE</span></a><span style="font-weight: 400"> in SQL databases.</span></p> <p><span style="font-weight: 400">But </span><b>with existing infrastructure, users can emulate recursive CTE using JavaScript UDFs. </b><span style="font-weight: 400">The following sections will demonstrate just how to do that and more!</span></p> <h2><span style="font-weight: 400">Solution to recursive queries</span></h2> <p><span style="font-weight: 400">To implement this solution, we need to create a JavaScript UDF that utilizes a breadth-first search algorithm to traverse the employee hierarchy. The UDF takes an </span><b>anchor query</b><span style="font-weight: 400">, a </span><b>recursive query</b><span style="font-weight: 400">, and </span><b>configuration options as parameters</b><span style="font-weight: 400">. The anchor query retrieves the initial set of employees, while the recursive query references the results of the previous iteration using the </span><i><span style="font-weight: 400">$1</span></i><span style="font-weight: 400"> parameter. Configuration options allow customization, including early exit criteria, arguments for inner queries, cycle detection, explain mode for query planning, and logging options.</span></p> <h3>How to use inner queries</h3> <p><span style="font-weight: 400">The anchor query gets the </span><b>root level documents</b><span style="font-weight: 400"> from the target collection.</span></p> <p><span style="font-weight: 400">The recursive query can use a </span><i><span style="font-weight: 400">JOIN </span></i><span style="font-weight: 400">clause with one side as </span><i><span style="font-weight: 400">$1</span></i><span style="font-weight: 400"> and the other as the target collection, to exploit the parent-child relationship and perform the traversal from one level to another.</span></p> <p><span style="font-weight: 400">In our function, </span><i><span style="font-weight: 400">$1</span></i><span style="font-weight: 400"> does what the CTE alias does in recursive CTE.</span></p> <p><span style="font-weight: 400">To better understand how we use SQL++ (N1QL) within JavaScript UDFs, take a look at</span> <a href="https://www.couchbase.com/blog/from-n1ql-to-javascript-and-back-part-1-introduction/"><span style="font-weight: 400">From N1QL to JavaScript and back</span></a><span style="font-weight: 400">.</span></p> <p><span style="font-weight: 400">Now let’s look at the process step by step. First of all, </span><b>does recursive query processing really need to be a recursive function?</b></p> <p><span style="font-weight: 400">No, this would be a bad choice considering time-complexity (the same functionality in recursive might be exponential, but linear in an iterative approach) and all the other issues like frames, etc., that come along with recursion. If interested, check out this </span><a href="https://www.baeldung.com/cs/convert-recursion-to-iteration"><span style="font-weight: 400">article</span></a><span style="font-weight: 400"> on converting tail recursion functions to iterative. Also, JS UDFs have a preset </span><b>max recursion depth of 128;</b><span style="font-weight: 400"> this is not preferable for what we are trying to do. </span></p> <p><span style="font-weight: 400">To put it simply, any iterative task does the following:</span><span style="font-weight: 400"><br /> </span></p> <p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14569" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_124659049-1024x439.png" alt="" width="900" height="386" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124659049-1024x439.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124659049-300x129.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124659049-768x330.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124659049.png 1235w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p><span style="font-weight: 400">We would like to acknowledge this </span><a href="https://www.postgresql.org/docs/current/queries-with.html"><span style="font-weight: 400">article</span></a><span style="font-weight: 400"> for its approach.</span></p> <h2><span style="font-weight: 400">Points to ponder</span></h2> <p><span style="font-weight: 400">How do we hold the </span><b>state expression</b><span style="font-weight: 400"> and pass it as a parameter to the query (recursive part here)?</span></p> <ul> <li style="list-style-type: none"> <ul> <li style="font-weight: 400"><span style="font-weight: 400">We use the SQL++ ability to pass </span><a href="https://docs.couchbase.com/server/current/n1ql/n1ql-intro/queriesandresults.html#named-placeholders"><span style="font-weight: 400">dynamic query parameters</span></a><span style="font-weight: 400"> and use parameterized queries to hold state value across levels.</span></li> <li style="font-weight: 400"><span style="font-weight: 400">We use </span><em>$1</em> in the recursive clause to refer previous iterations results, i.e., state expression</li> </ul> </li> </ul> <p><strong>How can we optimize?</strong></p> <ul> <li style="list-style-type: none"> <ul> <li style="font-weight: 400"><span style="font-weight: 400">Prepare both anchor and recursive queries initially so we can reuse the query plans at execution time.</span></li> <li style="font-weight: 400"><span style="font-weight: 400">Find a way to look at the query plan( similar to an </span><i><span style="font-weight: 400">EXPLAIN</span></i><span style="font-weight: 400"> statement) so we can generate appropriate indexes for inner statements (anchor and recursive).</span></li> </ul> </li> </ul> <p>The High-level Overview of the implementation is as follows:</p> <p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14570" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_124838894-1024x659.png" alt="" width="900" height="579" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124838894-1024x659.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124838894-300x193.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124838894-768x494.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_124838894.png 1294w" sizes="(max-width: 900px) 100vw, 900px" /></p> <h3><span style="font-weight: 400">Code for recursive CTE using JS UDFs </span></h3> <p><span style="font-weight: 400">This is a very naive implementation to get started and running. We set up the <em>Breadth-First-Search</em> algorithm, establishing the flow of order as per the overview above. Here is the code, from </span><a href="https://gist.github.com/GauravJayaraj/2d290f5398efe6edb8dc1b53e87556ae"><span style="font-weight: 400">this Gist</span></a><span style="font-weight: 400"> link:</span></p><!-- Urvanov Syntax Highlighter v2.8.37 --> <div id="urvanov-syntax-highlighter-67479ff75c91d175357213" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;"> <div class="crayon-toolbar" data-settings=" mouseover overlay hide delay" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><span class="crayon-title"></span> <div class="crayon-tools" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><div class="crayon-button urvanov-syntax-highlighter-nums-button" title="Toggle Line Numbers"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-plain-button" title="Toggle Plain Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-wrap-button" title="Toggle Line Wrap"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-expand-button" title="Expand Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-copy-button" title="Copy"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-popup-button" title="Open Code In New Window"><div class="urvanov-syntax-highlighter-button-icon"></div></div><span class="crayon-language">JavaScript</span></div></div> <div class="crayon-info" style="min-height: 16.8px !important; line-height: 16.8px !important;"></div> <div class="urvanov-syntax-highlighter-plain-wrap"><textarea wrap="soft" class="urvanov-syntax-highlighter-plain print-no" data-settings="dblclick" readonly style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;"> function recursive_cte(anchor , recursive, config) { let isLog = false; let anchorArgs=[]; let recursiveArgs=[]; let cycleFields=[]; let hash; let levelLimit = -1; let isExplain = false; let res = {"res":[], "log":[]} if(config!=undefined) { if(config.log!=undefined && config.log==true) { isLog = true; } if(config.anchorArgs!=undefined) { anchorArgs = config.anchorArgs; } if(config.recursiveArgs!=undefined) { recursiveArgs = config.recursiveArgs; } if(config.levelLimit!=undefined && config.levelLimit>0) { levelLimit = config.levelLimit; } if(config.cycleFields!=undefined && config.cycleFields.length>0) { res['log'].push("Got cycle fields "+ config.cycleFields) // for(const field of config.cycleFields) { // cycleFields.push(field); // } cycleFields = config.cycleFields; res['log'].push(cycleFields); // init hash hash = createhash(); } if(config.explain!=undefined) { isExplain = true; } } // init state recursiveArgs.push(0); // Prepare anchor statement let anchorPname; let anchorPlan; try{ const anchor_prep = N1QL("PREPARE FORCE "+anchor); for(const ap of anchor_prep) { anchorPname = ap["name"]; anchorPlan = ap["operator"]; } res['log'].push("prepared anchor"); } catch(err) { res['log'].push("couldn't prepare anchor"); throw err; } // prepare recursive statement let recursivePname; let recursivePlan; try{ const recursive_prep = N1QL("PREPARE FORCE "+recursive); for(const rp of recursive_prep) { recursivePname = rp["name"]; recursivePlan = rp["operator"]; } res['log'].push("prepared recursive"); } catch(err) { res['log'].push("couldn't prepare recursive"); throw err; } // state expression let workSet = [] // execute anchor try{ const anchorExec = N1QL("EXECUTE `"+anchorPname+"`",anchorArgs); for(const doc of anchorExec) { workSet.push(doc); } } catch(err) { res['log'].push("failed to execute anchor"); throw err; } // cycle check if(cycleFields.length>0) { res['log'].push("cycle check on fields "+cycleFields) workSet = cycleCheck(cycleFields, hash, workSet); } // populate root level( level 0 ) res['res'].push(...workSet); let level = 0; while(workSet.length!=0) { // exit on level condition if(levelLimit>0 && level>=levelLimit) { res['log'].push("Exit on level condition: levelLimit="+levelLimit.toString()) break; } // execute recursive query let newWorkSet = [] // set state $1 recursiveArgs[0] = workSet; try{ const recursiveExec = N1QL("EXECUTE `"+recursivePname+"`", recursiveArgs) // empty workSet to populate again for(const doc of recursiveExec) { newWorkSet.push(doc) } } catch(err){ res['log'].push("failed execute recursive"); throw err; } // cycle check if(cycleFields.length>0) { newWorkSet = cycleCheck(cycleFields, hash, newWorkSet); } if(newWorkSet.length==0) break; res["res"].push(...newWorkSet); // update state expression workSet = newWorkSet; level++; } if(isExplain){ res['log'].push("Anchor Plan:"); res['log'].push(anchorPlan); res['log'].push("Recursive Plan"); res["log"].push(recursivePlan); return res; } return isLog?res:res['res']; } function createhash() { let h = {}; const getVal = function(key) { return h[key]==undefined?false:true; } const setVal = function(key) { h[key] = true; } return {setVal, getVal}; } function cycleCheck(cycleFields, hash, workSet) { let cycleTrim = []; for(const doc of workSet) { let key = []; for(const field of cycleFields) { if(doc[field]!=undefined){ key.push(String(doc[field])); } } // create hashKey hashKey = key.join(String.fromCharCode(30)); if(hash.getVal(hashKey)==true){ continue; } else{ hash.setVal(hashKey); cycleTrim.push(doc); } } return cycleTrim; }</textarea></div> <div class="urvanov-syntax-highlighter-main" style=" max-height: 500px;"> <table class="crayon-table"> <tr class="urvanov-syntax-highlighter-row"> <td class="crayon-nums " data-settings="hide"> <div class="urvanov-syntax-highlighter-nums-content" style="font-size: 12px !important; line-height: 15px !important;"><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-1">1</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-2">2</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-3">3</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-4">4</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-5">5</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-6">6</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-7">7</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-8">8</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-9">9</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-10">10</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-11">11</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-12">12</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-13">13</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-14">14</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-15">15</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-16">16</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-17">17</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-18">18</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-19">19</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-20">20</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-21">21</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-22">22</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-23">23</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-24">24</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-25">25</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-26">26</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-27">27</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-28">28</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-29">29</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-30">30</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-31">31</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-32">32</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-33">33</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-34">34</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-35">35</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-36">36</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-37">37</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-38">38</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-39">39</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-40">40</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-41">41</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-42">42</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-43">43</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-44">44</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-45">45</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-46">46</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-47">47</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-48">48</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-49">49</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-50">50</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-51">51</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-52">52</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-53">53</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-54">54</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-55">55</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-56">56</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-57">57</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-58">58</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-59">59</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-60">60</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-61">61</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-62">62</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-63">63</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-64">64</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-65">65</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-66">66</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-67">67</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-68">68</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-69">69</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-70">70</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-71">71</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-72">72</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-73">73</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-74">74</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-75">75</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-76">76</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-77">77</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-78">78</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-79">79</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-80">80</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-81">81</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-82">82</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-83">83</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-84">84</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-85">85</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-86">86</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-87">87</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-88">88</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-89">89</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-90">90</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-91">91</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-92">92</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-93">93</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-94">94</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-95">95</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-96">96</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-97">97</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-98">98</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-99">99</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-100">100</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-101">101</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-102">102</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-103">103</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-104">104</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-105">105</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-106">106</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-107">107</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-108">108</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-109">109</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-110">110</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-111">111</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-112">112</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-113">113</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-114">114</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-115">115</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-116">116</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-117">117</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-118">118</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-119">119</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-120">120</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-121">121</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-122">122</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-123">123</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-124">124</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-125">125</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-126">126</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-127">127</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-128">128</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-129">129</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-130">130</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-131">131</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-132">132</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-133">133</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-134">134</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-135">135</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-136">136</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-137">137</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-138">138</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-139">139</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-140">140</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-141">141</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-142">142</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-143">143</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-144">144</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-145">145</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-146">146</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-147">147</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-148">148</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-149">149</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-150">150</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-151">151</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-152">152</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-153">153</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-154">154</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-155">155</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-156">156</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-157">157</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-158">158</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-159">159</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-160">160</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-161">161</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-162">162</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-163">163</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-164">164</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-165">165</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-166">166</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-167">167</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-168">168</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-169">169</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-170">170</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-171">171</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-172">172</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-173">173</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-174">174</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-175">175</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-176">176</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-177">177</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-178">178</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-179">179</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-180">180</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-181">181</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-182">182</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-183">183</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-184">184</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-185">185</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-186">186</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-187">187</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-188">188</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-189">189</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-190">190</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-191">191</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-192">192</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-193">193</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-194">194</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-195">195</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-196">196</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-197">197</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-198">198</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-199">199</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-200">200</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-201">201</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-202">202</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-203">203</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-204">204</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-205">205</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-206">206</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-207">207</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-208">208</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-209">209</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c91d175357213-210">210</div></div> </td> <td class="urvanov-syntax-highlighter-code"><div class="crayon-pre" style="font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-1"><span class="crayon-t">function</span><span class="crayon-h"> </span><span class="crayon-e">recursive_cte</span><span class="crayon-sy">(</span><span class="crayon-i">anchor</span><span class="crayon-h"> </span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">recursive</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-2"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">isLog</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">false</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-3"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">anchorArgs</span><span class="crayon-o">=</span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-4"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">recursiveArgs</span><span class="crayon-o">=</span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-5"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">cycleFields</span><span class="crayon-o">=</span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-6"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">hash</span><span class="crayon-sy">;</span><span class="crayon-h"> </span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-7"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">levelLimit</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-cn">1</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-8"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">isExplain</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">false</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-9"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-10"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">res</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">{</span><span class="crayon-s">"res"</span><span class="crayon-o">:</span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-s">"log"</span><span class="crayon-o">:</span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-11"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-12"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-13"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-14"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">log</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-h"> </span><span class="crayon-o">&&</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">log</span><span class="crayon-o">==</span><span class="crayon-t">true</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-15"><span class="crayon-h"> </span><span class="crayon-v">isLog</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">true</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-16"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-17"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-18"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">anchorArgs</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-19"><span class="crayon-h"> </span><span class="crayon-v">anchorArgs</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">anchorArgs</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-20"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-21"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-22"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">recursiveArgs</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-23"><span class="crayon-h"> </span><span class="crayon-v">recursiveArgs</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">recursiveArgs</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-24"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-25"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-26"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">levelLimit</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-h"> </span><span class="crayon-o">&&</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">levelLimit</span><span class="crayon-o">></span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-27"><span class="crayon-h"> </span><span class="crayon-v">levelLimit</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">levelLimit</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-28"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-29"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-30"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">cycleFields</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-h"> </span><span class="crayon-o">&&</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">.</span><span class="crayon-v">length</span><span class="crayon-o">></span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-31"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"Got cycle fields "</span><span class="crayon-o">+</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-32"><span class="crayon-h"> </span><span class="crayon-c">// for(const field of config.cycleFields) {</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-33"><span class="crayon-h"> </span><span class="crayon-c">// cycleFields.push(field);</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-34"><span class="crayon-h"> </span><span class="crayon-c">// }</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-35"><span class="crayon-h"> </span><span class="crayon-v">cycleFields</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-36"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-37"><span class="crayon-h"> </span><span class="crayon-c">// init hash</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-38"><span class="crayon-h"> </span><span class="crayon-v">hash</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">createhash</span><span class="crayon-sy">(</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-39"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-40"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-41"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-42"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">config</span><span class="crayon-sy">.</span><span class="crayon-v">explain</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-43"><span class="crayon-h"> </span><span class="crayon-v">isExplain</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">true</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-44"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-45"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-46"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-47"><span class="crayon-h"> </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-48"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-49"><span class="crayon-h"> </span><span class="crayon-c">// init state</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-50"><span class="crayon-h"> </span><span class="crayon-v">recursiveArgs</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-51"><span class="crayon-h"> </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-52"><span class="crayon-h"> </span><span class="crayon-c">// Prepare anchor statement</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-53"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">anchorPname</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-54"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">anchorPlan</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-55"><span class="crayon-h"> </span><span class="crayon-st">try</span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-56"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">anchor_prep</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">N1QL</span><span class="crayon-sy">(</span><span class="crayon-s">"PREPARE FORCE "</span><span class="crayon-o">+</span><span class="crayon-v">anchor</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-57"><span class="crayon-h"> </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-58"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">ap </span><span class="crayon-e">of </span><span class="crayon-v">anchor_prep</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-59"><span class="crayon-h"> </span><span class="crayon-v">anchorPname</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">ap</span><span class="crayon-sy">[</span><span class="crayon-s">"name"</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-60"><span class="crayon-h"> </span><span class="crayon-v">anchorPlan</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">ap</span><span class="crayon-sy">[</span><span class="crayon-s">"operator"</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-61"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-62"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-63"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"prepared anchor"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-64"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-65"><span class="crayon-h"> </span><span class="crayon-st">catch</span><span class="crayon-sy">(</span><span class="crayon-v">err</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-66"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"couldn't prepare anchor"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-67"><span class="crayon-h"> </span><span class="crayon-st">throw</span><span class="crayon-h"> </span><span class="crayon-v">err</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-68"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-69"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-70"><span class="crayon-h"> </span><span class="crayon-c">// prepare recursive statement</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-71"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-72"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">recursivePname</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-73"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">recursivePlan</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-74"><span class="crayon-h"> </span><span class="crayon-st">try</span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-75"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">recursive_prep</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">N1QL</span><span class="crayon-sy">(</span><span class="crayon-s">"PREPARE FORCE "</span><span class="crayon-o">+</span><span class="crayon-v">recursive</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-76"><span class="crayon-h"> </span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-77"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">rp </span><span class="crayon-e">of </span><span class="crayon-v">recursive_prep</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-78"><span class="crayon-h"> </span><span class="crayon-v">recursivePname</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">rp</span><span class="crayon-sy">[</span><span class="crayon-s">"name"</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-79"><span class="crayon-h"> </span><span class="crayon-v">recursivePlan</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">rp</span><span class="crayon-sy">[</span><span class="crayon-s">"operator"</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-80"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-81"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"prepared recursive"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-82"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-83"><span class="crayon-h"> </span><span class="crayon-st">catch</span><span class="crayon-sy">(</span><span class="crayon-v">err</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-84"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"couldn't prepare recursive"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-85"><span class="crayon-h"> </span><span class="crayon-st">throw</span><span class="crayon-h"> </span><span class="crayon-v">err</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-86"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-87"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-88"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-89"><span class="crayon-h"> </span><span class="crayon-c">// state expression </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-90"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">workSet</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-91"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-92"><span class="crayon-h"> </span><span class="crayon-c">// execute anchor </span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-93"><span class="crayon-h"> </span><span class="crayon-st">try</span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-94"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">anchorExec</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">N1QL</span><span class="crayon-sy">(</span><span class="crayon-s">"EXECUTE `"</span><span class="crayon-o">+</span><span class="crayon-v">anchorPname</span><span class="crayon-o">+</span><span class="crayon-s">"`"</span><span class="crayon-sy">,</span><span class="crayon-v">anchorArgs</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-95"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">doc </span><span class="crayon-e">of </span><span class="crayon-v">anchorExec</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-96"><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">doc</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-97"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-98"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-99"><span class="crayon-h"> </span><span class="crayon-st">catch</span><span class="crayon-sy">(</span><span class="crayon-v">err</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-100"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"failed to execute anchor"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-101"><span class="crayon-h"> </span><span class="crayon-st">throw</span><span class="crayon-h"> </span><span class="crayon-v">err</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-102"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-103"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-104"><span class="crayon-h"> </span><span class="crayon-c">// cycle check</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-105"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">.</span><span class="crayon-v">length</span><span class="crayon-o">></span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-106"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"cycle check on fields "</span><span class="crayon-o">+</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">)</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-107"><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">cycleCheck</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">hash</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-108"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-109"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-110"><span class="crayon-h"> </span><span class="crayon-c">// populate root level( level 0 )</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-111"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'res'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-sy">.</span><span class="crayon-sy">.</span><span class="crayon-sy">.</span><span class="crayon-v">workSet</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-112"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-113"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-114"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">level</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-cn">0</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-115"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-116"><span class="crayon-h"> </span><span class="crayon-st">while</span><span class="crayon-sy">(</span><span class="crayon-v">workSet</span><span class="crayon-sy">.</span><span class="crayon-v">length</span><span class="crayon-o">!=</span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-117"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-118"><span class="crayon-h"> </span><span class="crayon-c">// exit on level condition</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-119"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">levelLimit</span><span class="crayon-o">></span><span class="crayon-cn">0</span><span class="crayon-h"> </span><span class="crayon-o">&&</span><span class="crayon-h"> </span><span class="crayon-v">level</span><span class="crayon-o">>=</span><span class="crayon-v">levelLimit</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-120"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"Exit on level condition: levelLimit="</span><span class="crayon-o">+</span><span class="crayon-v">levelLimit</span><span class="crayon-sy">.</span><span class="crayon-e">toString</span><span class="crayon-sy">(</span><span class="crayon-sy">)</span><span class="crayon-sy">)</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-121"><span class="crayon-h"> </span><span class="crayon-st">break</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-122"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-123"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-124"><span class="crayon-h"> </span><span class="crayon-c">// execute recursive query</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-125"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">newWorkSet</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-126"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-127"><span class="crayon-h"> </span><span class="crayon-c">// set state $1</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-128"><span class="crayon-h"> </span><span class="crayon-v">recursiveArgs</span><span class="crayon-sy">[</span><span class="crayon-cn">0</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-129"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-130"><span class="crayon-h"> </span><span class="crayon-st">try</span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-131"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">recursiveExec</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">N1QL</span><span class="crayon-sy">(</span><span class="crayon-s">"EXECUTE `"</span><span class="crayon-o">+</span><span class="crayon-v">recursivePname</span><span class="crayon-o">+</span><span class="crayon-s">"`"</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">recursiveArgs</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-132"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-133"><span class="crayon-h"> </span><span class="crayon-c">// empty workSet to populate again</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-134"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">doc </span><span class="crayon-e">of </span><span class="crayon-v">recursiveExec</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-135"><span class="crayon-h"> </span><span class="crayon-v">newWorkSet</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">doc</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-136"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-137"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-138"><span class="crayon-h"> </span><span class="crayon-st">catch</span><span class="crayon-sy">(</span><span class="crayon-v">err</span><span class="crayon-sy">)</span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-139"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"failed execute recursive"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-140"><span class="crayon-h"> </span><span class="crayon-st">throw</span><span class="crayon-h"> </span><span class="crayon-v">err</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-141"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-142"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-143"><span class="crayon-h"> </span><span class="crayon-c">// cycle check</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-144"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">.</span><span class="crayon-v">length</span><span class="crayon-o">></span><span class="crayon-cn">0</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-145"><span class="crayon-h"> </span><span class="crayon-v">newWorkSet</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">cycleCheck</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">hash</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">newWorkSet</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-146"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-147"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-148"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">newWorkSet</span><span class="crayon-sy">.</span><span class="crayon-v">length</span><span class="crayon-o">==</span><span class="crayon-cn">0</span><span class="crayon-sy">)</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-149"><span class="crayon-h"> </span><span class="crayon-st">break</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-150"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-151"><span class="crayon-h"> </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-152"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">"res"</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-sy">.</span><span class="crayon-sy">.</span><span class="crayon-sy">.</span><span class="crayon-v">newWorkSet</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-153"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-154"><span class="crayon-h"> </span><span class="crayon-c">// update state expression</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-155"><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">newWorkSet</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-156"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-157"><span class="crayon-h"> </span><span class="crayon-v">level</span><span class="crayon-o">++</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-158"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-159"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-160"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">isExplain</span><span class="crayon-sy">)</span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-161"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"Anchor Plan:"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-162"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">anchorPlan</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-163"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'log'</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-s">"Recursive Plan"</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-164"><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">"log"</span><span class="crayon-sy">]</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">recursivePlan</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-165"><span class="crayon-h"> </span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">res</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-166"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-167"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-168"><span class="crayon-h"> </span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">isLog</span><span class="crayon-sy">?</span><span class="crayon-v">res</span><span class="crayon-o">:</span><span class="crayon-v">res</span><span class="crayon-sy">[</span><span class="crayon-s">'res'</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-169"><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-170"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-171"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-172"><span class="crayon-t">function</span><span class="crayon-h"> </span><span class="crayon-e">createhash</span><span class="crayon-sy">(</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-173"><span class="crayon-h"> </span><span class="crayon-i">let</span><span class="crayon-h"> </span><span class="crayon-v">h</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">{</span><span class="crayon-sy">}</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-174"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-175"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">getVal</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">function</span><span class="crayon-sy">(</span><span class="crayon-v">key</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-176"><span class="crayon-h"> </span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">h</span><span class="crayon-sy">[</span><span class="crayon-v">key</span><span class="crayon-sy">]</span><span class="crayon-o">==</span><span class="crayon-v">undefined</span><span class="crayon-sy">?</span><span class="crayon-t">false</span><span class="crayon-o">:</span><span class="crayon-t">true</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-177"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-178"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-179"><span class="crayon-h"> </span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-v">setVal</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">function</span><span class="crayon-sy">(</span><span class="crayon-v">key</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-180"><span class="crayon-h"> </span><span class="crayon-v">h</span><span class="crayon-sy">[</span><span class="crayon-v">key</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">true</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-181"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-182"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-183"><span class="crayon-h"> </span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-sy">{</span><span class="crayon-v">setVal</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">getVal</span><span class="crayon-sy">}</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-184"><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-185"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-186"><span class="crayon-t">function</span><span class="crayon-h"> </span><span class="crayon-e">cycleCheck</span><span class="crayon-sy">(</span><span class="crayon-v">cycleFields</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">hash</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">workSet</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-187"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">cycleTrim</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-188"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">doc </span><span class="crayon-e">of </span><span class="crayon-v">workSet</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-189"><span class="crayon-h"> </span><span class="crayon-e">let </span><span class="crayon-v">key</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-190"><span class="crayon-h"> </span><span class="crayon-st">for</span><span class="crayon-sy">(</span><span class="crayon-m">const</span><span class="crayon-h"> </span><span class="crayon-e">field </span><span class="crayon-e">of </span><span class="crayon-v">cycleFields</span><span class="crayon-sy">)</span><span class="crayon-h"> </span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-191"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">doc</span><span class="crayon-sy">[</span><span class="crayon-v">field</span><span class="crayon-sy">]</span><span class="crayon-o">!=</span><span class="crayon-v">undefined</span><span class="crayon-sy">)</span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-192"><span class="crayon-h"> </span><span class="crayon-v">key</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-t">String</span><span class="crayon-sy">(</span><span class="crayon-v">doc</span><span class="crayon-sy">[</span><span class="crayon-v">field</span><span class="crayon-sy">]</span><span class="crayon-sy">)</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-193"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-194"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-195"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-196"><span class="crayon-h"> </span><span class="crayon-c">// create hashKey</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-197"><span class="crayon-h"> </span><span class="crayon-v">hashKey</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-v">key</span><span class="crayon-sy">.</span><span class="crayon-e">join</span><span class="crayon-sy">(</span><span class="crayon-t">String</span><span class="crayon-sy">.</span><span class="crayon-e">fromCharCode</span><span class="crayon-sy">(</span><span class="crayon-cn">30</span><span class="crayon-sy">)</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-198"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-199"> </div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-200"><span class="crayon-h"> </span><span class="crayon-st">if</span><span class="crayon-sy">(</span><span class="crayon-v">hash</span><span class="crayon-sy">.</span><span class="crayon-e">getVal</span><span class="crayon-sy">(</span><span class="crayon-v">hashKey</span><span class="crayon-sy">)</span><span class="crayon-o">==</span><span class="crayon-t">true</span><span class="crayon-sy">)</span><span class="crayon-sy">{</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-201"><span class="crayon-h"> </span><span class="crayon-st">continue</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-202"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-203"><span class="crayon-h"> </span><span class="crayon-st">else</span><span class="crayon-sy">{</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-204"><span class="crayon-h"> </span><span class="crayon-v">hash</span><span class="crayon-sy">.</span><span class="crayon-e">setVal</span><span class="crayon-sy">(</span><span class="crayon-v">hashKey</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-205"><span class="crayon-h"> </span><span class="crayon-v">cycleTrim</span><span class="crayon-sy">.</span><span class="crayon-e">push</span><span class="crayon-sy">(</span><span class="crayon-v">doc</span><span class="crayon-sy">)</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-206"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-207"><span class="crayon-h"> </span><span class="crayon-sy">}</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-208"> </div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-209"><span class="crayon-h"> </span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">cycleTrim</span><span class="crayon-sy">;</span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c91d175357213-210"><span class="crayon-sy">}</span></div></div></td> </tr> </table> </div> </div> <!-- [Format Time: 0.0056 seconds] --> <p></p> <h3>How to add the function</h3> <p><span style="font-weight: 400">Here’s a </span><a href="https://docs.couchbase.com/server/current/guides/create-javascript-library.html"><span style="font-weight: 400">link</span></a><span style="font-weight: 400"> to add this to a JavaScript library (say </span><em>“mylibrary”</em><span style="font-weight: 400">) within your query service, and a </span><a href="https://docs.couchbase.com/server/current/guides/create-user-defined-function.html"><span style="font-weight: 400">link</span></a><span style="font-weight: 400"> to create the UDF from the added library.</span></p> <p><span style="font-weight: 400">Create the UDF from the library using SQL++: </span><span style="font-weight: 400"><br /> </span></p><!-- Urvanov Syntax Highlighter v2.8.37 --> <div id="urvanov-syntax-highlighter-67479ff75c927011883189" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;"> <div class="crayon-toolbar" data-settings=" mouseover overlay hide delay" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><span class="crayon-title"></span> <div class="crayon-tools" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><div class="crayon-button urvanov-syntax-highlighter-nums-button" title="Toggle Line Numbers"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-plain-button" title="Toggle Plain Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-wrap-button" title="Toggle Line Wrap"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-expand-button" title="Expand Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-copy-button" title="Copy"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-popup-button" title="Open Code In New Window"><div class="urvanov-syntax-highlighter-button-icon"></div></div></div></div> <div class="crayon-info" style="min-height: 16.8px !important; line-height: 16.8px !important;"></div> <div class="urvanov-syntax-highlighter-plain-wrap"><textarea wrap="soft" class="urvanov-syntax-highlighter-plain print-no" data-settings="dblclick" readonly style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;"> CREATE FUNCTION recursiveCte(anchor, recursive, config) LANGUAGE JAVASCRIPT as "recursive_cte" AT "mylibrary";</textarea></div> <div class="urvanov-syntax-highlighter-main" style=""> <table class="crayon-table"> <tr class="urvanov-syntax-highlighter-row"> <td class="crayon-nums " data-settings="show"> <div class="urvanov-syntax-highlighter-nums-content" style="font-size: 12px !important; line-height: 15px !important;"><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c927011883189-1">1</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c927011883189-2">2</div></div> </td> <td class="urvanov-syntax-highlighter-code"><div class="crayon-pre" style="font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c927011883189-1"><span class="crayon-e">CREATE </span><span class="crayon-t">FUNCTION</span><span class="crayon-h"> </span><span class="crayon-e">recursiveCte</span><span class="crayon-sy">(</span><span class="crayon-v">anchor</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">recursive</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">config</span><span class="crayon-sy">)</span><span class="crayon-h"> </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c927011883189-2"><span class="crayon-e">LANGUAGE </span><span class="crayon-e">JAVASCRIPT </span><span class="crayon-st">as</span><span class="crayon-h"> </span><span class="crayon-s">"recursive_cte"</span><span class="crayon-h"> </span><span class="crayon-i">AT</span><span class="crayon-h"> </span><span class="crayon-s">"mylibrary"</span><span class="crayon-sy">;</span></div></div></td> </tr> </table> </div> </div> <!-- [Format Time: 0.0004 seconds] --> <p><b>Usage</b></p> <p style="padding-left: 40px"><span style="font-weight: 400">Argument 1: <em>Anchor</em> query, string</span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400">Argument 2: <em>Recursive</em> query, string </span><span style="font-weight: 400">(uses </span><i><span style="font-weight: 400">$1(state expression)</span></i><span style="font-weight: 400"> to refer to the results of previous iteration )</span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400">Argument 3: Config <em>options</em>, object</span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400">All are </span><b>mandatory</b><span style="font-weight: 400">, but you can pass an </span><i><span style="font-weight: 400">empty object</span></i><span style="font-weight: 400">, i.e., </span><i><span style="font-weight: 400">{}</span></i><span style="font-weight: 400"> if you aren’t using any config options.</span></p> <p><span style="font-weight: 400"><br /> </span><b>Config Options</b><b></b></p> <p style="padding-left: 40px"><b>Early exit</b></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>levelLimit</em>(1 to N) – Specify the level at which we can stop. Level count starts at </span><i><span style="font-weight: 400">0</span></i><span style="font-weight: 400"> for anchor results, </span><i><span style="font-weight: 400">1</span></i><span style="font-weight: 400"> for first iteration/level, </span><i><span style="font-weight: 400">2</span></i><span style="font-weight: 400"> for second, etc.</span></p> <p style="padding-left: 40px"><b>Arguments to inner query</b></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>anchorArgs</em> – as named, e.g.,</span><i><span style="font-weight: 400">{“arg:1}</span></i><span style="font-weight: 400"> or positional arguments, e.g., </span><i><span style="font-weight: 400">[1]</span></i><span style="font-weight: 400"> to use in anchor query.</span></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>recursiveArgs</em> – Can only be positional arguments, and </span><i><span style="font-weight: 400">0</span></i><span style="font-weight: 400"> index must be reserved for state expression. For example: </span><i><span style="font-weight: 400">[0, 1] </span></i><span style="font-weight: 400">– always set 0th index (</span><i><span style="font-weight: 400">$1</span></i><span style="font-weight: 400"> arg) to </span><i><span style="font-weight: 400">0</span></i><span style="font-weight: 400">, so we can use it in the recursive clause as state expression.</span></p> <p style="padding-left: 40px"><b>Cycle detection</b></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>cycleFields</em> – Array of field names, e.g., </span><i><span style="font-weight: 400">[“_from”, “_to”]</span></i></p> <p style="padding-left: 40px"><b>Explain</b></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>explain</em> – Check query plan in logs (sets </span><i><span style="font-weight: 400">log </span></i><span style="font-weight: 400">by default)</span></p> <p style="padding-left: 40px"><b>Logs</b></p> <p style="padding-left: 40px"><span style="font-weight: 400"><em>log</em> – Display logs that help when you want to log while developing</span></p> <p> </p> <h2><span style="font-weight: 400">Sample Queries</span></h2> <p><span style="font-weight: 400"><br /> </span><b>1.</b><span style="font-weight: 400"> <b>Count numbers 1 to N</b> – simplest example of a query that shows how recursive CTE works.</span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400"> </span><span style="font-weight: 400"><br /> </span> <span style="font-weight: 400">Take a brief pause to think about how you could do this in N1QL without the function </span><span style="font-weight: 400">utility we developed now. Is it possible? (Or did we just make</span><b> N1QL Turing complete!</b><span style="font-weight: 400">)<br /> </span><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14571" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_125658889-1024x444.png" alt="" width="900" height="390" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125658889-1024x444.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125658889-300x130.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125658889-768x333.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125658889.png 1269w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p><b>2. Employees example</b> – refer to the employee collection we saw earlier.</p> <p style="padding-left: 40px"><span style="font-weight: 400">A. Find the organizational level of an employee</span><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14572" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_125805870-1024x424.png" alt="" width="900" height="373" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125805870-1024x424.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125805870-300x124.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125805870-768x318.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125805870.png 1251w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p style="padding-left: 40px">B. <span style="font-weight: 400">Per employee reports to hierarchy</span><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14573" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_125914592-1024x580.png" alt="" width="900" height="510" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125914592-1024x580.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125914592-300x170.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125914592-768x435.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_125914592.png 1225w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p><span style="font-weight: 400">Anchor query: </span></p><!-- Urvanov Syntax Highlighter v2.8.37 --> <div id="urvanov-syntax-highlighter-67479ff75c92a724448342" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" data-settings=" minimize scroll-mouseover" style=" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;"> <div class="crayon-toolbar" data-settings=" mouseover overlay hide delay" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><span class="crayon-title"></span> <div class="crayon-tools" style="font-size: 12px !important;height: 18px !important; line-height: 18px !important;"><div class="crayon-button urvanov-syntax-highlighter-nums-button" title="Toggle Line Numbers"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-plain-button" title="Toggle Plain Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-wrap-button" title="Toggle Line Wrap"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-expand-button" title="Expand Code"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-copy-button" title="Copy"><div class="urvanov-syntax-highlighter-button-icon"></div></div><div class="crayon-button urvanov-syntax-highlighter-popup-button" title="Open Code In New Window"><div class="urvanov-syntax-highlighter-button-icon"></div></div></div></div> <div class="crayon-info" style="min-height: 16.8px !important; line-height: 16.8px !important;"></div> <div class="urvanov-syntax-highlighter-plain-wrap"><textarea wrap="soft" class="urvanov-syntax-highlighter-plain print-no" data-settings="dblclick" readonly style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;"> SELECT e1.*, 0 as hlevel FROM `employees` e1 WHERE e1.manager_id=" || to_str(e.employee_id)</textarea></div> <div class="urvanov-syntax-highlighter-main" style=""> <table class="crayon-table"> <tr class="urvanov-syntax-highlighter-row"> <td class="crayon-nums " data-settings="show"> <div class="urvanov-syntax-highlighter-nums-content" style="font-size: 12px !important; line-height: 15px !important;"><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c92a724448342-1">1</div><div class="crayon-num crayon-striped-num" data-line="urvanov-syntax-highlighter-67479ff75c92a724448342-2">2</div><div class="crayon-num" data-line="urvanov-syntax-highlighter-67479ff75c92a724448342-3">3</div></div> </td> <td class="urvanov-syntax-highlighter-code"><div class="crayon-pre" style="font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c92a724448342-1"><span class="crayon-e">SELECT </span><span class="crayon-v">e1</span><span class="crayon-sy">.</span><span class="crayon-o">*</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-cn">0</span><span class="crayon-h"> </span><span class="crayon-st">as</span><span class="crayon-h"> </span><span class="crayon-e">hlevel </span></div><div class="crayon-line crayon-striped-line" id="urvanov-syntax-highlighter-67479ff75c92a724448342-2"><span class="crayon-i">FROM</span><span class="crayon-h"> </span><span class="crayon-sy">`</span><span class="crayon-v">employees</span><span class="crayon-sy">`</span><span class="crayon-h"> </span><span class="crayon-e">e1 </span></div><div class="crayon-line" id="urvanov-syntax-highlighter-67479ff75c92a724448342-3"><span class="crayon-e">WHERE </span><span class="crayon-v">e1</span><span class="crayon-sy">.</span><span class="crayon-v">manager_id</span><span class="crayon-o">=</span>"<span class="crayon-h"> </span><span class="crayon-o">||</span><span class="crayon-h"> </span><span class="crayon-e">to_str</span><span class="crayon-sy">(</span><span class="crayon-v">e</span><span class="crayon-sy">.</span><span class="crayon-v">employee_id</span><span class="crayon-sy">)</span></div></div></td> </tr> </table> </div> </div> <!-- [Format Time: 0.0002 seconds] --> <p>This can look too verbose when adding a <em>WHERE</em> predicate from outer query. W<span style="font-weight: 400">e can use the </span><em>anchorArgs</em> option<span style="font-weight: 400"> to mitigate this!</span></p> <h3><span style="font-weight: 400">Arguments (anchorArgs/recursiveArgs)</span></h3> <p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14574" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_130029549-1024x191.png" alt="" width="900" height="168" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130029549-1024x191.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130029549-300x56.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130029549-768x143.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130029549.png 1253w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p style="padding-left: 40px"><strong>Explain</strong></p> <p style="padding-left: 40px"><span style="font-weight: 400">Provide </span><span style="font-weight: 400">{“explain”: true} – </span><span style="font-weight: 400">you can see the query plan in the log field </span></p> <p style="padding-left: 40px"><strong>Early Exit</strong></p> <p style="padding-left: 40px"><span style="font-weight: 400">Set </span><i><span style="font-weight: 400">levelLimit </span></i><span style="font-weight: 400">like </span><i><span style="font-weight: 400">{“levelLimit”:2}</span></i><span style="font-weight: 400"> – if you only want 2 levels of recursion</span></p> <p> </p> <p style="padding-left: 40px"><strong>Cycle Detection</strong></p> <p style="padding-left: 40px"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14575" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_130205451-1024x334.png" alt="" width="900" height="294" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130205451-1024x334.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130205451-300x98.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130205451-768x250.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130205451.png 1271w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p style="padding-left: 40px"><b>Without cycle detection </b><span style="font-weight: 400">the query to find employee level hierarchy will go into an </span><b>infinite loop </b><i><span style="font-weight: 400">and crash on function timeout, wasting CPU resources.</span></i><span style="font-weight: 400"><br /> </span><span style="font-weight: 400"><br /> </span><span style="font-weight: 400">Considering that when we work on graph data it is highly likely that we have cycles present and it is the </span><b>responsibility of the caller of the function to to set cycle detection of appropriate fields.</b></p> <p style="padding-left: 40px"><span style="font-weight: 400">Here, the </span><i><span style="font-weight: 400">“employee_id”</span></i><span style="font-weight: 400">, </span><i><span style="font-weight: 400">“manager_id”</span></i><span style="font-weight: 400"> pair is sufficient to exit on cycle.</span></p> <p style="padding-left: 40px"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-14576" src="https://www.couchbase.com/blog/wp-content/uploads/2023/06/image_2023-06-23_130306815-1024x312.png" alt="" width="900" height="274" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130306815-1024x312.png 1024w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130306815-300x92.png 300w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130306815-768x234.png 768w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2023/06/image_2023-06-23_130306815.png 1259w" sizes="(max-width: 900px) 100vw, 900px" /></p> <p>Thank you for following on this challenging topic, we hope it reveals more options for some of your recursive querying challenges!</p> <h2><span style="font-weight: 400">References</span></h2> <ul> <li style="list-style-type: none"> <ul> <li style="font-weight: 400"><a href="https://www.baeldung.com/cs/convert-recursion-to-iteration"><span style="font-weight: 400">Convert Recursive to Iterative Functions (Baeldung)</span></a></li> <li style="font-weight: 400"><a href="https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/index.html"><span style="font-weight: 400">SQL++ Language Reference docs</span></a></li> <li style="font-weight: 400"><a href="https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/?_ga=2.234064094.1723037650.1675387315-1783168968.1675058199#-graphlookup--aggregation-"><span style="font-weight: 400">MongoDB graphLookup reference</span></a></li> <li style="font-weight: 400"><a href="https://docs.snowflake.com/en/user-guide/queries-cte#recursive-ctes-and-hierarchical-data"><span style="font-weight: 400">Snowflake recursive CTE reference</span></a></li> <li style="font-weight: 400"><a href="https://www.couchbase.com/blog/from-n1ql-to-javascript-and-back-part-1-introduction/"><span style="font-weight: 400">Blog: From N1QL to JavaScript and Back – Part 1</span></a></li> <li style="font-weight: 400"><a href="https://www.postgresql.org/docs/current/queries-with.html"><span style="font-weight: 400">PostgreSQL query reference, WITH clause</span></a></li> <li style="font-weight: 400"><a href="https://docs.couchbase.com/server/current/n1ql/n1ql-intro/queriesandresults.html#named-placeholders"><span style="font-weight: 400">SQL++ Queries and Results docs</span></a></li> <li style="font-weight: 400"><a href="https://docs.couchbase.com/server/current/guides/create-javascript-library.html"><span style="font-weight: 400">Creating a JavaScript library docs</span></a></li> <li style="font-weight: 400"><a href="https://docs.couchbase.com/server/current/guides/create-user-defined-function.html"><span style="font-weight: 400">Creating User Defined Functions (UDF) in Couchbase</span></a></li> </ul> </li> </ul> <!--begin code --> <div class="pp-multiple-authors-boxes-wrapper pp-multiple-authors-wrapper pp-multiple-authors-layout-simple_list multiple-authors-target-the-content box-post-id-14469 box-instance-id-1 ppma_boxes_14469" data-post_id="14469" data-instance_id="1" data-additional_class="pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content" data-original_class="pp-multiple-authors-boxes-wrapper pp-multiple-authors-wrapper box-post-id-14469 box-instance-id-1"> <span class="ppma-layout-prefix"></span> <div class="ppma-author-category-wrap"> <span class="ppma-category-group ppma-category-group-1 category-index-0"> <ul class="pp-multiple-authors-boxes-ul author-ul-0"> <li class="pp-multiple-authors-boxes-li author_index_0 author_gauravjayaraj has-avatar"> <div class="pp-author-boxes-avatar"> <div class="avatar-image"> <img alt='Gaurav Jayaraj - Intern, Couchbase R&D' src='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=35&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=70&d=mm&r=g 2x' class='avatar avatar-35 photo' height='35' width='35' /> </div> </div> <div class="pp-author-boxes-avatar-details"> <div class="pp-author-boxes-name multiple-authors-name"><a href="https://www.couchbase.com/blog/author/gauravjayaraj/" rel="author" title="Gaurav Jayaraj - Intern, Couchbase R&D" class="author url fn">Gaurav Jayaraj - Intern, Couchbase R&D</a></div> </div> </li> </ul> </span> </div> <span class="ppma-layout-suffix"></span> </div> <!--end code --> <style> .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-avatar img { width: 35px !important; height: 35px !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-avatar img { border-radius: 0% !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-meta a { background-color: #655997 !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-meta a { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-meta a:hover { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_email-profile-data { background-color: #655997 !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_email-profile-data { border-radius: 100% !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_email-profile-data { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_email-profile-data:hover { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_url-profile-data { background-color: #655997 !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_url-profile-data { border-radius: 100% !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_url-profile-data { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-user_url-profile-data:hover { color: #ffffff !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-recent-posts-title { border-bottom-style: dotted !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-author-boxes-recent-posts-item { text-align: left !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-multiple-authors-boxes-li { border-style: solid !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-multiple-authors-boxes-li { border-color: #999999 !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .pp-multiple-authors-boxes-li { color: #3c434a !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-category-wrap .ppma-category-group { margin-bottom: px !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-category-wrap .ppma-category-group { margin-right: px !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-category-wrap { font-size: px !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list.multiple-authors-target-the-content .ppma-author-category-wrap .ppma-category-group-title { font-weight: !important; } .pp-multiple-authors-boxes-wrapper.pp-multiple-authors-layout-simple_list .pp-multiple-authors-boxes-ul li { border-left: none !important; border-right: none !important; } </style> <div class='heateor_sss_sharing_container heateor_sss_vertical_sharing heateor_sss_bottom_sharing' style='width:44px;right: -10px;top: 190px;-webkit-box-shadow:none;box-shadow:none;' data-heateor-sss-href='https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/'><div class="heateor_sss_sharing_ul"><a aria-label="X" class="heateor_sss_button_x" href="https://twitter.com/intent/tweet?text=Recursive%20Query%20Processing%20in%20SQL%2B%2B%20%28N1QL%29&url=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F" title="X" rel="nofollow noopener" target="_blank" style="font-size:32px!important;box-shadow:none;display:inline-block;vertical-align:middle"><span class="heateor_sss_svg heateor_sss_s__default heateor_sss_s_x" style="background-color:#2a2a2a;width:40px;height:40px;margin:0;display:inline-block;opacity:1;float:left;font-size:32px;box-shadow:none;display:inline-block;font-size:16px;padding:0 4px;vertical-align:middle;background-repeat:repeat;overflow:hidden;padding:0;cursor:pointer;box-sizing:content-box"><svg width="100%" height="100%" style="display:block;" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#fff" d="M21.751 7h3.067l-6.7 7.658L26 25.078h-6.172l-4.833-6.32-5.531 6.32h-3.07l7.167-8.19L6 7h6.328l4.37 5.777L21.75 7Zm-1.076 16.242h1.7L11.404 8.74H9.58l11.094 14.503Z"></path></svg></span></a><a aria-label="Linkedin" class="heateor_sss_button_linkedin" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F" title="Linkedin" rel="nofollow noopener" target="_blank" style="font-size:32px!important;box-shadow:none;display:inline-block;vertical-align:middle"><span class="heateor_sss_svg heateor_sss_s__default heateor_sss_s_linkedin" style="background-color:#0077b5;width:40px;height:40px;margin:0;display:inline-block;opacity:1;float:left;font-size:32px;box-shadow:none;display:inline-block;font-size:16px;padding:0 4px;vertical-align:middle;background-repeat:repeat;overflow:hidden;padding:0;cursor:pointer;box-sizing:content-box"><svg style="display:block;" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 32 32"><path d="M6.227 12.61h4.19v13.48h-4.19V12.61zm2.095-6.7a2.43 2.43 0 0 1 0 4.86c-1.344 0-2.428-1.09-2.428-2.43s1.084-2.43 2.428-2.43m4.72 6.7h4.02v1.84h.058c.56-1.058 1.927-2.176 3.965-2.176 4.238 0 5.02 2.792 5.02 6.42v7.395h-4.183v-6.56c0-1.564-.03-3.574-2.178-3.574-2.18 0-2.514 1.7-2.514 3.46v6.668h-4.187V12.61z" fill="#fff"></path></svg></span></a><a aria-label="Facebook" class="heateor_sss_facebook" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F" title="Facebook" rel="nofollow noopener" target="_blank" style="font-size:32px!important;box-shadow:none;display:inline-block;vertical-align:middle"><span class="heateor_sss_svg" style="background-color:#0765FE;width:40px;height:40px;margin:0;display:inline-block;opacity:1;float:left;font-size:32px;box-shadow:none;display:inline-block;font-size:16px;padding:0 4px;vertical-align:middle;background-repeat:repeat;overflow:hidden;padding:0;cursor:pointer;box-sizing:content-box"><svg style="display:block;" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 32 32"><path fill="#fff" d="M28 16c0-6.627-5.373-12-12-12S4 9.373 4 16c0 5.628 3.875 10.35 9.101 11.647v-7.98h-2.474V16H13.1v-1.58c0-4.085 1.849-5.978 5.859-5.978.76 0 2.072.15 2.608.298v3.325c-.283-.03-.775-.045-1.386-.045-1.967 0-2.728.745-2.728 2.683V16h3.92l-.673 3.667h-3.247v8.245C23.395 27.195 28 22.135 28 16Z"></path></svg></span></a><a aria-label="Copy Link" class="heateor_sss_button_copy_link" title="Copy Link" rel="noopener" href="https://www.couchbase.com/blog/recursive-query-processing-in-sql-n1ql/" onclick="event.preventDefault()" style="font-size:32px!important;box-shadow:none;display:inline-block;vertical-align:middle"><span class="heateor_sss_svg heateor_sss_s__default heateor_sss_s_copy_link" style="background-color:#ffc112;width:40px;height:40px;margin:0;display:inline-block;opacity:1;float:left;font-size:32px;box-shadow:none;display:inline-block;font-size:16px;padding:0 4px;vertical-align:middle;background-repeat:repeat;overflow:hidden;padding:0;cursor:pointer;box-sizing:content-box"><svg style="display:block;" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-4 -4 40 40"><path fill="#fff" d="M24.412 21.177c0-.36-.126-.665-.377-.917l-2.804-2.804a1.235 1.235 0 0 0-.913-.378c-.377 0-.7.144-.97.43.026.028.11.11.255.25.144.14.24.236.29.29s.117.14.2.256c.087.117.146.232.177.344.03.112.046.236.046.37 0 .36-.126.666-.377.918a1.25 1.25 0 0 1-.918.377 1.4 1.4 0 0 1-.373-.047 1.062 1.062 0 0 1-.345-.175 2.268 2.268 0 0 1-.256-.2 6.815 6.815 0 0 1-.29-.29c-.14-.142-.223-.23-.25-.254-.297.28-.445.607-.445.984 0 .36.126.664.377.916l2.778 2.79c.243.243.548.364.917.364.36 0 .665-.118.917-.35l1.982-1.97c.252-.25.378-.55.378-.9zm-9.477-9.504c0-.36-.126-.665-.377-.917l-2.777-2.79a1.235 1.235 0 0 0-.913-.378c-.35 0-.656.12-.917.364L7.967 9.92c-.254.252-.38.553-.38.903 0 .36.126.665.38.917l2.802 2.804c.242.243.547.364.916.364.377 0 .7-.14.97-.418-.026-.027-.11-.11-.255-.25s-.24-.235-.29-.29a2.675 2.675 0 0 1-.2-.255 1.052 1.052 0 0 1-.176-.344 1.396 1.396 0 0 1-.047-.37c0-.36.126-.662.377-.914.252-.252.557-.377.917-.377.136 0 .26.015.37.046.114.03.23.09.346.175.117.085.202.153.256.2.054.05.15.148.29.29.14.146.222.23.25.258.294-.278.442-.606.442-.983zM27 21.177c0 1.078-.382 1.99-1.146 2.736l-1.982 1.968c-.745.75-1.658 1.12-2.736 1.12-1.087 0-2.004-.38-2.75-1.143l-2.777-2.79c-.75-.747-1.12-1.66-1.12-2.737 0-1.106.392-2.046 1.183-2.818l-1.186-1.185c-.774.79-1.708 1.186-2.805 1.186-1.078 0-1.995-.376-2.75-1.13l-2.803-2.81C5.377 12.82 5 11.903 5 10.826c0-1.08.382-1.993 1.146-2.738L8.128 6.12C8.873 5.372 9.785 5 10.864 5c1.087 0 2.004.382 2.75 1.146l2.777 2.79c.75.747 1.12 1.66 1.12 2.737 0 1.105-.392 2.045-1.183 2.817l1.186 1.186c.774-.79 1.708-1.186 2.805-1.186 1.078 0 1.995.377 2.75 1.132l2.804 2.804c.754.755 1.13 1.672 1.13 2.75z"/></svg></span></a></div><div class="heateorSssClear"></div></div> </div><!-- .entry-content --> <div class="entry-meta"> <ul class="meta-list"> <!-- Categories --> <li class="meta-cat"> <span>Posted in:</span> <a href="https://www.couchbase.com/blog/category/couchbase-server/" rel="category tag">Couchbase Server</a>, <a href="https://www.couchbase.com/blog/category/data-modeling/" rel="category tag">Data Modeling</a>, <a href="https://www.couchbase.com/blog/category/javascript/" rel="category tag">JavaScript</a>, <a href="https://www.couchbase.com/blog/category/n1ql-query/" rel="category tag">SQL++ / N1QL Query</a> </li> <!-- Tags --> <li class="meta-tag"> <span>Tagged in:</span> <a href="https://www.couchbase.com/blog/tag/query-language/" rel="tag">Query Language</a>, <a href="https://www.couchbase.com/blog/tag/recursive-queries/" rel="tag">recursive queries</a>, <a href="https://www.couchbase.com/blog/tag/udf/" rel="tag">UDF</a> </li> </ul><!-- .meta-list --> </div><!-- .entry-meta --> </article><!-- #post-## --> <h2 class="widget-title">Author</h2> <div class="author-profile"> <a class="author-profile-avatar" href="https://www.couchbase.com/blog/author/gauravjayaraj/" title="Posts by Gaurav Jayaraj - Intern, Couchbase R&D"><img alt='' src='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=65&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/5513af284b334a520b66164e298cab68?s=130&d=mm&r=g 2x' class='avatar avatar-65 photo' height='65' width='65' loading='lazy' decoding='async'/></a> <div class="author-profile-info"> <h3 class="author-profile-title"> Posted by Gaurav Jayaraj - Intern, Couchbase R&D </h3> <div class="author-description"> <p>Gaurav Jayaraj is an intern in the Query team at Couchbase R&D. Gaurav is pursuing his Bachelors in Computer Science from PES University, Bangalore.</p> </div> <div class="author-profile-links"> <a href="https://www.couchbase.com/blog/author/gauravjayaraj/"><i class="fa fa-pencil-square"></i> All Posts</a> </div> </div><!-- .author-drawer-text --> </div><!-- .author-profile --> <!-- Comment toggle and share buttons --> <div class="share-comment show"> <a class="comments-toggle button" href="#"> <span><i class="fa fa-comments"></i> Leave a comment </span> <span><i class="fa fa-times"></i> Hide comments</span> </a> </div> <div id="comments" class="comments-area show"> <div id="respond" class="comment-respond"> <h3 id="reply-title" class="comment-reply-title"><span>Leave a reply</span> <small><a rel="nofollow" id="cancel-comment-reply-link" href="/blog/recursive-query-processing-in-sql-n1ql/#respond" style="display:none;">Cancel reply</a></small></h3><p class="must-log-in">You must be <a href="https://www.couchbase.com/blog/wp-login.php?redirect_to=https%3A%2F%2Fwww.couchbase.com%2Fblog%2Frecursive-query-processing-in-sql-n1ql%2F">logged in</a> to post a comment.</p><div class="heateor_sl_outer_login_container"><div class="heateor_sl_title">Login with your Social ID</div><div class="heateor_sl_login_container"><ul class="heateor_sl_login_ul"><li><i class="heateorSlLogin heateorSlFacebookBackground heateorSlFacebookLogin" alt="Login with Facebook" title="Login with Facebook" onclick="heateorSlCommentFormLogin = true;heateorSlInitiateLogin( this, 'facebook' )" ><div class="heateorSlFacebookLogoContainer"><ss style="display:block" class="heateorSlLoginSvg heateorSlFacebookLoginSvg"></ss></div></i></li><li><i class="heateorSlLogin heateorSlXBackground heateorSlXLogin" alt="Login with X" title="Login with X" onclick="heateorSlCommentFormLogin = true;heateorSlInitiateLogin( this, 'x' )" ><ss style="display:block" class="heateorSlLoginSvg heateorSlXLoginSvg"></ss></i></li><li><i class="heateorSlLogin heateorSlLinkedinBackground heateorSlLinkedinLogin" alt="Login with Linkedin" title="Login with Linkedin" onclick="heateorSlCommentFormLogin = true;heateorSlInitiateLogin( this, 'linkedin' )" ><ss style="display:block" class="heateorSlLoginSvg heateorSlLinkedinLoginSvg"></ss></i></li><li><i id="heateorSlGoogleButton" class="heateorSlLogin heateorSlGoogleBackground heateorSlGoogleLogin" alt="Login with Google" title="Login with Google" onclick="heateorSlCommentFormLogin = true;heateorSlInitiateLogin( this, 'google' )" ><ss style="display:block" class="heateorSlLoginSvg heateorSlGoogleLoginSvg"></ss></i></li><li><i class="heateorSlLogin heateorSlGithubBackground heateorSlGithubLogin" alt="Login with Github" title="Login with Github" onclick="heateorSlCommentFormLogin = true;heateorSlInitiateLogin( this, 'github' )" ><ss style="display:block" class="heateorSlLoginSvg heateorSlGithubLoginSvg"></ss></i></li></ul></div></div><div style="clear:both; margin-bottom: 6px"></div> </div><!-- #respond --> </div><!-- #comments --> </main><!-- #main --> </div><!-- #primary --> <div data-rocket-location-hash="ea16ef889527d5d1c9e156a75abbb7f0" id="secondary" class="widget-area"> <aside id="search-3" class="widget widget_search"><h2 class="widget-title">Search our blog</h2> <form role="search" method="get" id="searchform" class="searchform" action="https://www.couchbase.com/blog/"> <div> <label class="screen-reader-text" for="s">Search for:</label> <input type="text" value="" name="s" id="s" class="search-input" placeholder="Search here..." /> <button type="submit" id="searchsubmit"> <i class="fa fa-search"></i> <span>Search</span> </button> </div> </form></aside><aside id="media_image-5" class="widget widget_media_image"><a href="https://info.couchbase.com/master-ai-at-the-edge-with-mobile-sync-search-and-security-2024november"><img width="733" height="1139" src="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/11/Prog2-Blog-Ad-732x1138-1.jpg" class="image wp-image-16553 attachment-full size-full" alt="" style="max-width: 100%; height: auto;" decoding="async" loading="lazy" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/11/Prog2-Blog-Ad-732x1138-1.jpg 733w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/11/Prog2-Blog-Ad-732x1138-1-193x300.jpg 193w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/11/Prog2-Blog-Ad-732x1138-1-659x1024.jpg 659w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/11/Prog2-Blog-Ad-732x1138-1-300x466.jpg 300w" sizes="(max-width: 733px) 100vw, 733px" /></a></aside><aside id="media_image-6" class="widget widget_media_image"><a href="https://www.couchbase.com/couchbase-capella-test-drive/"><img width="732" height="1138" src="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/06/732x1138-CB-Blog-2.png" class="image wp-image-15871 attachment-full size-full" alt="" style="max-width: 100%; height: auto;" decoding="async" loading="lazy" srcset="https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/06/732x1138-CB-Blog-2.png 732w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/06/732x1138-CB-Blog-2-193x300.png 193w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/06/732x1138-CB-Blog-2-659x1024.png 659w, https://www.couchbase.com/blog/wp-content/uploads/sites/1/2024/06/732x1138-CB-Blog-2-300x466.png 300w" sizes="(max-width: 732px) 100vw, 732px" /></a></aside> <aside id="recent-posts-2" class="widget widget_recent_entries"> <h2 class="widget-title">Recent Posts</h2> <ul> <li> <a href="https://www.couchbase.com/blog/ai-agents-the-coming-tidal-wave-of-observability-data/">AI Agents & the Coming Tidal Wave of Observability Data</a> </li> <li> <a href="https://www.couchbase.com/blog/tesco-utilizes-couchbase-during-peak-black-friday-traffic/">How Tesco Utilizes Couchbase to Manage Millions of Products During Peak Black Friday Traffic</a> </li> <li> <a href="https://www.couchbase.com/blog/what-is-an-ai-agent/">What is an AI Agent? An Explainer</a> </li> <li> <a href="https://www.couchbase.com/blog/capella-iq-insights/">New Capella iQ Insights: Turn Data Into Actionable Insights</a> </li> <li> <a href="https://www.couchbase.com/blog/agentic-ai/">Everything You Need to Know About Agentic AI</a> </li> </ul> </aside><aside id="custom_html-12" class="widget_text widget widget_custom_html"><h2 class="widget-title">Top Posts</h2><div class="textwidget custom-html-widget"><ul class="wpp-list"> <li class=""> <a href="https://www.couchbase.com/blog/app-development-costs/" class="wpp-post-title" target="_self" rel="noopener">App Development Costs (A Breakdown)</a> <span class="wpp-meta post-stats"></span></li> <li class=""> <a href="https://www.couchbase.com/blog/conceptual-physical-logical-data-models/" class="wpp-post-title" target="_self" rel="noopener">Data Modeling Explained: Conceptual, Physical, Logical</a> <span class="wpp-meta post-stats"></span></li> <li class=""> <a href="https://www.couchbase.com/blog/what-is-data-analysis/" class="wpp-post-title" target="_self" rel="noopener">What Is Data Analysis? Types, Methods, and Tools for Research</a> <span class="wpp-meta post-stats"></span></li> <li class=""> <a href="https://www.couchbase.com/blog/data-analysis-methods/" class="wpp-post-title" target="_self" rel="noopener">Data Analysis Methods: Qualitative vs. Quantitative Techniques</a> <span class="wpp-meta post-stats"></span></li> <li class=""> <a href="https://www.couchbase.com/blog/transactional-databases/" class="wpp-post-title" target="_self" rel="noopener">What is a Transactional Database?</a> <span class="wpp-meta post-stats"></span></li> </ul></div></aside><aside id="categories-2" class="widget widget_categories"><h2 class="widget-title">Blog Topics</h2><form action="https://www.couchbase.com/blog" method="get"><label class="screen-reader-text" for="cat">Blog Topics</label><select name='cat' id='cat' class='postform'> <option value='-1'>Select Topic</option> <option class="level-0" value="1811">.NET</option> <option class="level-0" value="2294">Analytics</option> <option class="level-0" value="2370">Android</option> <option class="level-0" value="1814">Application Design</option> <option class="level-0" value="9416">Backup</option> <option class="level-0" value="1815">Best Practices and Tutorials</option> <option class="level-0" value="9986">C++</option> <option class="level-0" value="2381">Community</option> <option class="level-0" value="3917">Company</option> <option class="level-0" value="2242">Connectors</option> <option class="level-0" value="1821">Couchbase Architecture</option> <option class="level-0" value="9284">Couchbase Autonomous Operator</option> <option class="level-0" value="2225">Couchbase Capella</option> <option class="level-0" value="9385">Couchbase Connect</option> <option class="level-0" value="8905">Couchbase Global Secondary Index</option> <option class="level-0" value="7667">Couchbase Lite</option> <option class="level-0" value="1810">Couchbase Mobile</option> <option class="level-0" value="2201">Couchbase SDK</option> <option class="level-0" value="1816">Couchbase Server</option> <option class="level-0" value="3918">Culture</option> <option class="level-0" value="6319">Customers</option> <option class="level-0" value="1819">Data Modeling</option> <option class="level-0" value="7666">Edge computing</option> <option class="level-0" value="2273">Eventing</option> <option class="level-0" value="3919">Executive</option> <option class="level-0" value="2371">Flutter</option> <option class="level-0" value="2165">Full-Text Search</option> <option class="level-0" value="9973">Generative AI (GenAI)</option> <option class="level-0" value="8683">Geospatial</option> <option class="level-0" value="2453">Global Secondary Index</option> <option class="level-0" value="1820">GoLang</option> <option class="level-0" value="9381">Indexing</option> <option class="level-0" value="1818">Java</option> <option class="level-0" value="9327">JavaScript</option> <option class="level-0" value="9593">Kotlin</option> <option class="level-0" value="2322">Kubernetes</option> <option class="level-0" value="9374">License</option> <option class="level-0" value="2334">Monitoring</option> <option class="level-0" value="9411">Multi-Dimensional Scaling</option> <option class="level-0" value="1822">Node.js</option> <option class="level-0" value="9410">Objective-C</option> <option class="level-0" value="9921">Partners</option> <option class="level-0" value="9417">Performance</option> <option class="level-0" value="9408">PHP</option> <option class="level-0" value="9139">Python</option> <option class="level-0" value="9407">Ruby</option> <option class="level-0" value="9140">Rust</option> <option class="level-0" value="9141">Scala</option> <option class="level-0" value="9336">Scopes and Collections</option> <option class="level-0" value="9936">Search</option> <option class="level-0" value="1813">Security</option> <option class="level-0" value="2389">Solutions</option> <option class="level-0" value="6342">Spring</option> <option class="level-0" value="6343">Spring Boot</option> <option class="level-0" value="1812">SQL++ / N1QL Query</option> <option class="level-0" value="9409">Swift</option> <option class="level-0" value="2366">Sync Gateway</option> <option class="level-0" value="7277">Text Analysis</option> <option class="level-0" value="2396">Transactions</option> <option class="level-0" value="1">Uncategorized</option> <option class="level-0" value="9375">Upgrades</option> <option class="level-0" value="9937">Vector Search</option> <option class="level-0" value="2351">Xamarin</option> <option class="level-0" value="9415">XDCR</option> </select> </form><script type="rocketlazyloadscript" data-rocket-type="text/javascript"> /* <![CDATA[ */ (function() { var dropdown = document.getElementById( "cat" ); function onCatChange() { if ( dropdown.options[ dropdown.selectedIndex ].value > 0 ) { dropdown.parentNode.submit(); } } dropdown.onchange = onCatChange; })(); /* ]]> */ </script> </aside> </div><!-- #secondary .widget-area --> </div> </div> <!-- Promotion banner --> <section data-rocket-location-hash="cd6edf3876d85f488a5c21cc54ff96ff" class="promotion-banner promotion-banner-blue"> <div data-rocket-location-hash="f9357140ee36883ea6064de5d7279a99" class="container"> <div data-rocket-location-hash="4001fd299c908bfbd3082d75647c17d6" class="flex justify-center align-center flex-wrap flex-coloumn"> <div class='promotion-banner-title'>Stay informed about Couchbase Blogs</div> <div class=" mailpoet_form_popup_overlay "></div> <div id="mailpoet_form_3" class=" mailpoet_form mailpoet_form_shortcode mailpoet_form_position_ mailpoet_form_animation_ " > <style type="text/css"> #mailpoet_form_3 .mailpoet_form { } #mailpoet_form_3 .mailpoet_column_with_background { padding: 10px; } #mailpoet_form_3 .mailpoet_form_column:not(:first-child) { margin-left: 20px; } #mailpoet_form_3 .mailpoet_paragraph { line-height: 20px; margin-bottom: 20px; } #mailpoet_form_3 .mailpoet_segment_label, #mailpoet_form_3 .mailpoet_text_label, #mailpoet_form_3 .mailpoet_textarea_label, #mailpoet_form_3 .mailpoet_select_label, #mailpoet_form_3 .mailpoet_radio_label, #mailpoet_form_3 .mailpoet_checkbox_label, #mailpoet_form_3 .mailpoet_list_label, #mailpoet_form_3 .mailpoet_date_label { display: block; font-weight: normal; } #mailpoet_form_3 .mailpoet_text, #mailpoet_form_3 .mailpoet_textarea, #mailpoet_form_3 .mailpoet_select, #mailpoet_form_3 .mailpoet_date_month, #mailpoet_form_3 .mailpoet_date_day, #mailpoet_form_3 .mailpoet_date_year, #mailpoet_form_3 .mailpoet_date { display: block; } #mailpoet_form_3 .mailpoet_text, #mailpoet_form_3 .mailpoet_textarea { width: 200px; } #mailpoet_form_3 .mailpoet_checkbox { } #mailpoet_form_3 .mailpoet_submit { } #mailpoet_form_3 .mailpoet_divider { } #mailpoet_form_3 .mailpoet_message { } #mailpoet_form_3 .mailpoet_form_loading { width: 30px; text-align: center; line-height: normal; } #mailpoet_form_3 .mailpoet_form_loading > span { width: 5px; height: 5px; background-color: #5b5b5b; }#mailpoet_form_3{border-radius: 0px;text-align: left;}#mailpoet_form_3 form.mailpoet_form {padding: 20px;}#mailpoet_form_3{width: 100%;}#mailpoet_form_3 .mailpoet_message {margin: 0; padding: 0 20px;}#mailpoet_form_3 .mailpoet_paragraph.last {margin-bottom: 0} @media (max-width: 500px) {#mailpoet_form_3 {background-image: none;}} @media (min-width: 500px) {#mailpoet_form_3 .last .mailpoet_paragraph:last-child {margin-bottom: 0}} @media (max-width: 500px) {#mailpoet_form_3 .mailpoet_form_column:last-child .mailpoet_paragraph:last-child {margin-bottom: 0}} </style> <form target="_self" method="post" action="https://www.couchbase.com/blog/wp-admin/admin-post.php?action=mailpoet_subscription_form" class="mailpoet_form mailpoet_form_form mailpoet_form_shortcode" novalidate data-delay="" data-exit-intent-enabled="" data-font-family="" data-cookie-expiration-time="" > <input type="hidden" name="data[form_id]" value="3" /> <input type="hidden" name="token" value="05a6784353" /> <input type="hidden" name="api_version" value="v1" /> <input type="hidden" name="endpoint" value="subscribers" /> <input type="hidden" name="mailpoet_method" value="subscribe" /> <label class="mailpoet_hp_email_label" style="display: none !important;">Please leave this field empty<input type="email" name="data[email]"/></label><div class='mailpoet_form_columns_container'><div class="mailpoet_form_columns mailpoet_paragraph mailpoet_stack_on_mobile"><div class="mailpoet_form_column" style="flex-basis:100%;"><div class="mailpoet_paragraph "><label for="form_email_3" class="mailpoet_text_label" data-automation-id="form_email_label" >Email <span class="mailpoet_required" aria-hidden="true">*</span></label><input type="email" autocomplete="email" class="mailpoet_text" id="form_email_3" name="data[form_field_NWQ2NjcyODkxZWY1X2VtYWls]" title="Email" value="" style="width:100%;box-sizing:border-box;padding:5px;margin: 0 auto 0 0;" data-automation-id="form_email" data-parsley-errors-container=".mailpoet_error_yxamq" data-parsley-required="true" required aria-required="true" data-parsley-minlength="6" data-parsley-maxlength="150" data-parsley-type-message="This value should be a valid email." data-parsley-required-message="This field is required."/><span class="mailpoet_error_yxamq"></span></div> <div class="mailpoet_paragraph "><fieldset><input type="hidden" value="1" name="data[cf_1]" /><label class="mailpoet_checkbox_label" for="mailpoet_checkbox_1" ><input type="checkbox" class="mailpoet_checkbox" id="mailpoet_checkbox_1" name="data[cf_1]" value="1" data-parsley-errors-container=".mailpoet_error_2turz" data-parsley-required="true" required aria-required="true" data-parsley-required-message="This field is required." data-parsley-group="custom_field_1" /> By checking this box, you acknowledge our <a href="https://www.couchbase.com/privacy-policy/" target="_blank">Privacy Policy</a>. You may unsubscribe at any time.</label></fieldset><span class="mailpoet_error_2turz"></span></div> </div> </div></div> <div class="mailpoet_recaptcha" data-sitekey="6Le6oqUhAAAAAMLYrNBqdvBFuynXWkoDTMjTu5Tt" > <div class="mailpoet_recaptcha_container"></div> <noscript> <div> <div class="mailpoet_recaptcha_noscript_container"> <div> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Le6oqUhAAAAAMLYrNBqdvBFuynXWkoDTMjTu5Tt" frameborder="0" scrolling="no"> </iframe> </div> </div> <div class="mailpoet_recaptcha_noscript_input"> <textarea id="g-recaptcha-response" name="data[recaptcha]" class="g-recaptcha-response"> </textarea> </div> </div> </noscript> <input class="mailpoet_recaptcha_field" type="hidden" name="recaptchaWidgetId"> </div><div class="parsley-errors-list parsley-required mailpoet_error_recaptcha">This field is required.</div><div class="mailpoet_paragraph "><input type="submit" class="mailpoet_submit" value="Subscribe!" data-automation-id="subscribe-submit-button" style="width:100%;box-sizing:border-box;padding:5px;margin: 0 auto 0 0;border-color:transparent;" /><span class="mailpoet_form_loading"><span class="mailpoet_bounce1"></span><span class="mailpoet_bounce2"></span><span class="mailpoet_bounce3"></span></span></div> <div class="mailpoet_message"> <p class="mailpoet_validate_success" style="display:none;" >Check your inbox or spam folder to confirm your subscription. </p> <p class="mailpoet_validate_error" style="display:none;" > </p> </div> </form> </div> </div> </div> </section> <footer data-rocket-location-hash="258cfd76a8627b4cd9024c2ee152d05d" id="colophon" class="site-footer dev-cb-footer" role="contentinfo"> <!-- Footer design as developer couchbase --> <div data-rocket-location-hash="ebb6345ca8433823e36718140b99288d" class="wrapper"> <div data-rocket-location-hash="2e018bf1e98ff90321f1bb0a27e93ffe" class="footer-links flex flex-wrap"> <div class="footer-logo w-full md:w-1/4 mb-4"> <a href="https://www.couchbase.com/"> <img src="https://www.couchbase.com/blog/wp-content/themes/couchbase/images/Couchbase-R-B.svg" alt="Couchbase" width="203" height="47"> </a> </div> <aside id="nav_menu-6" class="widget w-1/2 md:w-1/4 mb-4 widget_nav_menu"><div class="menu-footercol-1-container"><ul id="menu-footercol-1" class="menu"><li id="menu-item-11108" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11108"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/">Documentation</a></li> <li id="menu-item-11109" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11109"><a href="https://www.couchbase.com/downloads/">Downloads</a></li> <li id="menu-item-11110" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11110"><a target="_blank" rel="noopener" href="https://www.couchbase.com/forums/">Forums</a></li> <li id="menu-item-11111" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-11111"><a href="https://www.couchbase.com/blog/">Blog</a></li> <li id="menu-item-11112" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11112"><a href="https://www.couchbase.com/resources/">Resources</a></li> </ul></div></aside><aside id="nav_menu-3" class="widget w-1/2 md:w-1/4 mb-4 widget_nav_menu"><div class="menu-footercol-2-container"><ul id="menu-footercol-2" class="menu"><li id="menu-item-11103" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11103"><a target="_blank" rel="noopener" href="https://support.couchbase.com/">Support Login</a></li> <li id="menu-item-11104" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11104"><a target="_blank" rel="noopener" href="https://learn.couchbase.com/store/?utf8=%E2%9C%93&ss=1&ct=78327&commit=Filter">Training</a></li> <li id="menu-item-11105" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11105"><a href="https://www.couchbase.com/careers/">Careers</a></li> <li id="menu-item-11106" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11106"><a href="https://www.couchbase.com/resources/webcasts-and-events/">Events</a></li> <li id="menu-item-11107" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11107"><a target="_blank" rel="noopener" href="https://docs.couchbase.com/home/sdk.html">SDKs</a></li> </ul></div></aside><aside id="nav_menu-5" class="widget w-1/2 md:w-1/4 mb-4 widget_nav_menu"><div class="menu-footercol-3-container"><ul id="menu-footercol-3" class="menu"><li id="menu-item-11101" class="fa fa-twitter menu-item menu-item-type-custom menu-item-object-custom menu-item-11101"><a target="_blank" rel="noopener" href="https://twitter.com/couchbase/">Twitter</a></li> <li id="menu-item-11102" class="fa fa-linkedin-square menu-item menu-item-type-custom menu-item-object-custom menu-item-11102"><a target="_blank" rel="noopener" href="https://www.linkedin.com/company/couchbase/">LinkedIn</a></li> <li id="menu-item-11100" class="fa fa-github menu-item menu-item-type-custom menu-item-object-custom menu-item-11100"><a target="_blank" rel="noopener" href="https://github.com/couchbase/">Github</a></li> <li id="menu-item-11099" class="fa fa-stack-overflow menu-item menu-item-type-custom menu-item-object-custom menu-item-11099"><a target="_blank" rel="noopener" href="https://stackoverflow.com/tags/couchbase/info/">StackOverflow</a></li> </ul></div></aside> </div> <div data-rocket-location-hash="207751028a7e5fba21fc6847c08bc1a5" class="footer-terms"> <div class='text-sm'> © 2024 Couchbase, Inc. Couchbase and the Couchbase logo are registered trademarks of Couchbase, Inc. All third party trademarks (including logos and icons) referenced by Couchbase, Inc. remain the property of their respective owners. </div> <nav class="footer-terms-menu" role="navigation"> <div class="menu-footer-container"><ul id="menu-footer" class="menu"><li id="menu-item-1111" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1111"><a href="https://www.couchbase.com/terms-of-use/">Terms of Use</a></li> <li id="menu-item-1112" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1112"><a href="https://www.couchbase.com/privacy-policy/">Privacy Policy</a></li> <li id="menu-item-5199" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5199"><a href="https://www.couchbase.com/cookie-policy/">Cookie Policy</a></li> <li id="menu-item-11118" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-11118"><a href="https://www.couchbase.com/support-policy/">Support Policy</a></li> <li id="menu-item-5200" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5200"><a target="_blank" rel="noopener" href="https://info.couchbase.com/unsubscribe-or-manage-preferences.html">Marketing Preference Center</a></li> </ul></div> </nav><!-- .footer-navigation --> </div> </div> </footer><!-- #colophon --> <span class="scroll-top show"></span> <!-- GTM Container placement set to footer --> <!-- Google Tag Manager (noscript) --> <noscript><iframe src="https://metrics.couchbase.com/ns.html?id=GTM-MVPNN2" height="0" width="0" style="display:none;visibility:hidden" aria-hidden="true"></iframe></noscript> <!-- End Google Tag Manager (noscript) --><script type="rocketlazyloadscript" data-rocket-type="text/javascript">var algolia = {"debug":false,"application_id":"NI1G57N08Q","search_api_key":"4b05a6fa0de7ca588c885b058f20130b","powered_by_enabled":false,"query":"","autocomplete":{"sources":[{"admin_name":"All posts","index_id":"searchable_posts","index_name":"newprod_searchable_posts","label":"All posts","max_suggestions":5,"position":1,"tmpl_suggestion":"autocomplete-post-suggestion","enabled":true}],"input_selector":"input[name='s']:not(.no-autocomplete):not(#adminbar-search)"},"indices":{"searchable_posts":{"name":"newprod_searchable_posts","id":"searchable_posts","enabled":true,"replicas":[]}}};</script> <script type="text/html" id="tmpl-autocomplete-header"> <div class="autocomplete-header"> <div class="autocomplete-header-title">{{{ data.label }}}</div> <div class="clear"></div> </div> </script> <script type="text/html" id="tmpl-autocomplete-post-suggestion"> <a class="suggestion-link" href="{{ data.permalink }}" title="{{ data.post_title }}"> <# if ( data.images.thumbnail ) { #> <img class="suggestion-post-thumbnail" src="{{ data.images.thumbnail.url }}" alt="{{ data.post_title }}"> <# } #> <div class="suggestion-post-attributes"> <span class="suggestion-post-title">{{{ data._highlightResult.post_title.value }}}</span> <# if ( data._snippetResult['content'] ) { #> <span class="suggestion-post-content">{{{ data._snippetResult['content'].value }}}</span> <# } #> </div> </a> </script> <script type="text/html" id="tmpl-autocomplete-term-suggestion"> <a class="suggestion-link" href="{{ data.permalink }}" title="{{ data.name }}"> <svg viewBox="0 0 21 21" width="21" height="21"> <svg width="21" height="21" viewBox="0 0 21 21"> <path d="M4.662 8.72l-1.23 1.23c-.682.682-.68 1.792.004 2.477l5.135 5.135c.7.693 1.8.688 2.48.005l1.23-1.23 5.35-5.346c.31-.31.54-.92.51-1.36l-.32-4.29c-.09-1.09-1.05-2.06-2.15-2.14l-4.3-.33c-.43-.03-1.05.2-1.36.51l-.79.8-2.27 2.28-2.28 2.27zm9.826-.98c.69 0 1.25-.56 1.25-1.25s-.56-1.25-1.25-1.25-1.25.56-1.25 1.25.56 1.25 1.25 1.25z" fill-rule="evenodd"></path> </svg> </svg> <span class="suggestion-post-title">{{{ data._highlightResult.name.value }}}</span> </a> </script> <script type="text/html" id="tmpl-autocomplete-user-suggestion"> <a class="suggestion-link user-suggestion-link" href="{{ data.posts_url }}" title="{{ data.display_name }}"> <# if ( data.avatar_url ) { #> <img class="suggestion-user-thumbnail" src="{{ data.avatar_url }}" alt="{{ data.display_name }}"> <# } #> <span class="suggestion-post-title">{{{ data._highlightResult.display_name.value }}}</span> </a> </script> <script type="text/html" id="tmpl-autocomplete-footer"> <div class="autocomplete-footer"> <div class="autocomplete-footer-branding"> <a href="#" class="algolia-powered-by-link" title="Algolia"> <svg width="150px" height="25px" viewBox="0 0 572 64"><path fill="#36395A" d="M16 48.3c-3.4 0-6.3-.6-8.7-1.7A12.4 12.4 0 0 1 1.9 42C.6 40 0 38 0 35.4h6.5a6.7 6.7 0 0 0 3.9 6c1.4.7 3.3 1.1 5.6 1.1 2.2 0 4-.3 5.4-1a7 7 0 0 0 3-2.4 6 6 0 0 0 1-3.4c0-1.5-.6-2.8-1.9-3.7-1.3-1-3.3-1.6-5.9-1.8l-4-.4c-3.7-.3-6.6-1.4-8.8-3.4a10 10 0 0 1-3.3-7.9c0-2.4.6-4.6 1.8-6.4a12 12 0 0 1 5-4.3c2.2-1 4.7-1.6 7.5-1.6s5.5.5 7.6 1.6a12 12 0 0 1 5 4.4c1.2 1.8 1.8 4 1.8 6.7h-6.5a6.4 6.4 0 0 0-3.5-5.9c-1-.6-2.6-1-4.4-1s-3.2.3-4.4 1c-1.1.6-2 1.4-2.6 2.4-.5 1-.8 2-.8 3.1a5 5 0 0 0 1.5 3.6c1 1 2.6 1.7 4.7 1.9l4 .3c2.8.2 5.2.8 7.2 1.8 2.1 1 3.7 2.2 4.9 3.8a9.7 9.7 0 0 1 1.7 5.8c0 2.5-.7 4.7-2 6.6a13 13 0 0 1-5.6 4.4c-2.4 1-5.2 1.6-8.4 1.6Zm35.6 0c-2.6 0-4.8-.4-6.7-1.3a13 13 0 0 1-4.7-3.5 17.1 17.1 0 0 1-3.6-10.4v-1c0-2 .3-3.8 1-5.6a13 13 0 0 1 7.3-8.3 15 15 0 0 1 6.3-1.4A13.2 13.2 0 0 1 64 24.3c1 2.2 1.6 4.6 1.6 7.2V34H39.4v-4.3h21.8l-1.8 2.2c0-2-.3-3.7-.9-5.1a7.3 7.3 0 0 0-2.7-3.4c-1.2-.7-2.7-1.1-4.6-1.1s-3.4.4-4.7 1.3a8 8 0 0 0-2.9 3.6c-.6 1.5-.9 3.3-.9 5.4 0 2 .3 3.7 1 5.3a7.9 7.9 0 0 0 2.8 3.7c1.3.8 3 1.3 5 1.3s3.8-.5 5.1-1.3c1.3-1 2.1-2 2.4-3.2h6a11.8 11.8 0 0 1-7 8.7 16 16 0 0 1-6.4 1.2ZM80 48c-2.2 0-4-.3-5.7-1a8.4 8.4 0 0 1-3.7-3.3 9.7 9.7 0 0 1-1.3-5.2c0-2 .5-3.8 1.5-5.2a9 9 0 0 1 4.3-3.1c1.8-.7 4-1 6.7-1H89v4.1h-7.5c-2 0-3.4.5-4.4 1.4-1 1-1.6 2.1-1.6 3.6s.5 2.7 1.6 3.6c1 1 2.5 1.4 4.4 1.4 1.1 0 2.2-.2 3.2-.7 1-.4 1.9-1 2.6-2 .6-1 1-2.4 1-4.2l1.7 2.1c-.2 2-.7 3.8-1.5 5.2a9 9 0 0 1-3.4 3.3 12 12 0 0 1-5.3 1Zm9.5-.7v-8.8h-1v-10c0-1.8-.5-3.2-1.4-4.1-1-1-2.4-1.4-4.2-1.4a142.9 142.9 0 0 0-10.2.4v-5.6a74.8 74.8 0 0 1 8.6-.4c3 0 5.5.4 7.5 1.2s3.4 2 4.4 3.6c1 1.7 1.4 4 1.4 6.7v18.4h-5Zm12.9 0V17.8h5v12.3h-.2c0-4.2 1-7.4 2.8-9.5a11 11 0 0 1 8.3-3.1h1v5.6h-2a9 9 0 0 0-6.3 2.2c-1.5 1.5-2.2 3.6-2.2 6.4v15.6h-6.4Zm34.4 1a15 15 0 0 1-6.6-1.3c-1.9-.9-3.4-2-4.7-3.5a15.5 15.5 0 0 1-2.7-5c-.6-1.7-1-3.6-1-5.4v-1c0-2 .4-3.8 1-5.6a15 15 0 0 1 2.8-4.9c1.3-1.5 2.8-2.6 4.6-3.5a16.4 16.4 0 0 1 13.3.2c2 1 3.5 2.3 4.8 4a12 12 0 0 1 2 6H144c-.2-1.6-1-3-2.2-4.1a7.5 7.5 0 0 0-5.2-1.7 8 8 0 0 0-4.7 1.3 8 8 0 0 0-2.8 3.6 13.8 13.8 0 0 0 0 10.3c.6 1.5 1.5 2.7 2.8 3.6s2.8 1.3 4.8 1.3c1.5 0 2.7-.2 3.8-.8a7 7 0 0 0 2.6-2c.7-1 1-2 1.2-3.2h6.2a11 11 0 0 1-2 6.2 15.1 15.1 0 0 1-11.8 5.5Zm19.7-1v-40h6.4V31h-1.3c0-3 .4-5.5 1.1-7.6a9.7 9.7 0 0 1 3.5-4.8A9.9 9.9 0 0 1 172 17h.3c3.5 0 6 1.1 7.9 3.5 1.7 2.3 2.6 5.7 2.6 10v16.8h-6.4V29.6c0-2.1-.6-3.8-1.8-5a6.4 6.4 0 0 0-4.8-1.8c-2 0-3.7.7-5 2a7.8 7.8 0 0 0-1.9 5.5v17h-6.4Zm63.8 1a12.2 12.2 0 0 1-10.9-6.2 19 19 0 0 1-1.8-7.3h1.4v12.5h-5.1v-40h6.4v19.8l-2 3.5c.2-3.1.8-5.7 1.9-7.7a11 11 0 0 1 4.4-4.5c1.8-1 3.9-1.5 6.1-1.5a13.4 13.4 0 0 1 12.8 9.1c.7 1.9 1 3.8 1 6v1c0 2.2-.3 4.1-1 6a13.6 13.6 0 0 1-13.2 9.4Zm-1.2-5.5a8.4 8.4 0 0 0 7.9-5c.7-1.5 1.1-3.3 1.1-5.3s-.4-3.8-1.1-5.3a8.7 8.7 0 0 0-3.2-3.6 9.6 9.6 0 0 0-9.2-.2 8.5 8.5 0 0 0-3.3 3.2c-.8 1.4-1.3 3-1.3 5v2.3a9 9 0 0 0 1.3 4.8 9 9 0 0 0 3.4 3c1.4.7 2.8 1 4.4 1Zm27.3 3.9-10-28.9h6.5l9.5 28.9h-6Zm-7.5 12.2v-5.7h4.9c1 0 2-.1 2.9-.4a4 4 0 0 0 2-1.4c.4-.7.9-1.6 1.2-2.7l8.6-30.9h6.2l-9.3 32.4a14 14 0 0 1-2.5 5 8.9 8.9 0 0 1-4 2.8c-1.5.6-3.4.9-5.6.9h-4.4Zm9-12.2v-5.2h6.4v5.2H248Z"></path><path fill="#003DFF" d="M534.4 9.1H528a.8.8 0 0 1-.7-.7V1.8c0-.4.2-.7.6-.8l6.5-1c.4 0 .8.2.9.6v7.8c0 .4-.4.7-.8.7zM428 35.2V.8c0-.5-.3-.8-.7-.8h-.2l-6.4 1c-.4 0-.7.4-.7.8v35c0 1.6 0 11.8 12.3 12.2.5 0 .8-.4.8-.8V43c0-.4-.3-.7-.6-.8-4.5-.5-4.5-6-4.5-7zm106.5-21.8H528c-.4 0-.7.4-.7.8v34c0 .4.3.8.7.8h6.5c.4 0 .8-.4.8-.8v-34c0-.5-.4-.8-.8-.8zm-17.7 21.8V.8c0-.5-.3-.8-.8-.8l-6.5 1c-.4 0-.7.4-.7.8v35c0 1.6 0 11.8 12.3 12.2.4 0 .8-.4.8-.8V43c0-.4-.3-.7-.7-.8-4.4-.5-4.4-6-4.4-7zm-22.2-20.6a16.5 16.5 0 0 1 8.6 9.3c.8 2.2 1.3 4.8 1.3 7.5a19.4 19.4 0 0 1-4.6 12.6 14.8 14.8 0 0 1-5.2 3.6c-2 .9-5.2 1.4-6.8 1.4a21 21 0 0 1-6.7-1.4 15.4 15.4 0 0 1-8.6-9.3 21.3 21.3 0 0 1 0-14.4 15.2 15.2 0 0 1 8.6-9.3c2-.8 4.3-1.2 6.7-1.2s4.6.4 6.7 1.2zm-6.7 27.6c2.7 0 4.7-1 6.2-3s2.2-4.3 2.2-7.8-.7-6.3-2.2-8.3-3.5-3-6.2-3-4.7 1-6.1 3c-1.5 2-2.2 4.8-2.2 8.3s.7 5.8 2.2 7.8 3.5 3 6.2 3zm-88.8-28.8c-6.2 0-11.7 3.3-14.8 8.2a18.6 18.6 0 0 0 4.8 25.2c1.8 1.2 4 1.8 6.2 1.7s.1 0 .1 0h.9c4.2-.7 8-4 9.1-8.1v7.4c0 .4.3.7.8.7h6.4a.7.7 0 0 0 .7-.7V14.2c0-.5-.3-.8-.7-.8h-13.5zm6.3 26.5a9.8 9.8 0 0 1-5.7 2h-.5a10 10 0 0 1-9.2-14c1.4-3.7 5-6.3 9-6.3h6.4v18.3zm152.3-26.5h13.5c.5 0 .8.3.8.7v33.7c0 .4-.3.7-.8.7h-6.4a.7.7 0 0 1-.8-.7v-7.4c-1.2 4-4.8 7.4-9 8h-.1a4.2 4.2 0 0 1-.5.1h-.9a10.3 10.3 0 0 1-7-2.6c-4-3.3-6.5-8.4-6.5-14.2 0-3.7 1-7.2 3-10 3-5 8.5-8.3 14.7-8.3zm.6 28.4c2.2-.1 4.2-.6 5.7-2V21.7h-6.3a9.8 9.8 0 0 0-9 6.4 10.2 10.2 0 0 0 9.1 13.9h.5zM452.8 13.4c-6.2 0-11.7 3.3-14.8 8.2a18.5 18.5 0 0 0 3.6 24.3 10.4 10.4 0 0 0 13 .6c2.2-1.5 3.8-3.7 4.5-6.1v7.8c0 2.8-.8 5-2.2 6.3-1.5 1.5-4 2.2-7.5 2.2l-6-.3c-.3 0-.7.2-.8.5l-1.6 5.5c-.1.4.1.8.5 1h.1c2.8.4 5.5.6 7 .6 6.3 0 11-1.4 14-4.1 2.7-2.5 4.2-6.3 4.5-11.4V14.2c0-.5-.4-.8-.8-.8h-13.5zm6.3 8.2v18.3a9.6 9.6 0 0 1-5.6 2h-1a10.3 10.3 0 0 1-8.8-14c1.4-3.7 5-6.3 9-6.3h6.4zM291 31.5A32 32 0 0 1 322.8 0h30.8c.6 0 1.2.5 1.2 1.2v61.5c0 1.1-1.3 1.7-2.2 1l-19.2-17a18 18 0 0 1-11 3.4 18.1 18.1 0 1 1 18.2-14.8c-.1.4-.5.7-.9.6-.1 0-.3 0-.4-.2l-3.8-3.4c-.4-.3-.6-.8-.7-1.4a12 12 0 1 0-2.4 8.3c.4-.4 1-.5 1.6-.2l14.7 13.1v-46H323a26 26 0 1 0 10 49.7c.8-.4 1.6-.2 2.3.3l3 2.7c.3.2.3.7 0 1l-.2.2a32 32 0 0 1-47.2-28.6z"></path></svg> </a> </div> </div> </script> <script type="text/html" id="tmpl-autocomplete-empty"> <div class="autocomplete-empty"> No results matched your query <span class="empty-query">"{{ data.query }}"</span> </div> </script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript"> window.addEventListener('load', function () { /* Initialize Algolia client */ var client = algoliasearch( algolia.application_id, algolia.search_api_key ); /** * Algolia hits source method. * * This method defines a custom source to use with autocomplete.js. * * @param object $index Algolia index object. * @param object $params Options object to use in search. */ var algoliaHitsSource = function( index, params ) { return function( query, callback ) { index .search( query, params ) .then( function( response ) { callback( response.hits, response ); }) .catch( function( error ) { callback( [] ); }); } } /* Setup autocomplete.js sources */ var sources = []; algolia.autocomplete.sources.forEach( function( config, i ) { var suggestion_template = wp.template( config[ 'tmpl_suggestion' ] ); sources.push( { source: algoliaHitsSource( client.initIndex( config[ 'index_name' ] ), { hitsPerPage: config[ 'max_suggestions' ], attributesToSnippet: [ 'content:10' ], highlightPreTag: '__ais-highlight__', highlightPostTag: '__/ais-highlight__' } ), templates: { header: function () { return wp.template( 'autocomplete-header' )( { label: _.escape( config[ 'label' ] ) } ); }, suggestion: function ( hit ) { if ( hit.escaped === true ) { return suggestion_template( hit ); } hit.escaped = true; for ( var key in hit._highlightResult ) { /* We do not deal with arrays. */ if ( typeof hit._highlightResult[ key ].value !== 'string' ) { continue; } hit._highlightResult[ key ].value = _.escape( hit._highlightResult[ key ].value ); hit._highlightResult[ key ].value = hit._highlightResult[ key ].value.replace( /__ais-highlight__/g, '<em>' ).replace( /__\/ais-highlight__/g, '</em>' ); } for ( var key in hit._snippetResult ) { /* We do not deal with arrays. */ if ( typeof hit._snippetResult[ key ].value !== 'string' ) { continue; } hit._snippetResult[ key ].value = _.escape( hit._snippetResult[ key ].value ); hit._snippetResult[ key ].value = hit._snippetResult[ key ].value.replace( /__ais-highlight__/g, '<em>' ).replace( /__\/ais-highlight__/g, '</em>' ); } return suggestion_template( hit ); } } } ); } ); /* Setup dropdown menus */ document.querySelectorAll( algolia.autocomplete.input_selector ).forEach( function( element ) { var config = { debug: algolia.debug, hint: false, openOnFocus: true, appendTo: 'body', templates: { empty: wp.template( 'autocomplete-empty' ) } }; if ( algolia.powered_by_enabled ) { config.templates.footer = wp.template( 'autocomplete-footer' ); } /* Instantiate autocomplete.js */ var autocomplete = algoliaAutocomplete( element, config, sources ) .on( 'autocomplete:selected', function ( e, suggestion ) { /* Redirect the user when we detect a suggestion selection. */ window.location.href = suggestion.permalink ?? suggestion.posts_url; // Users use the `posts_url` property instead of `permalink`. } ); /* Force the dropdown to be re-drawn on scroll to handle fixed containers. */ window.addEventListener( 'scroll', function() { if ( autocomplete.autocomplete.getWrapper().style.display === "block" ) { autocomplete.autocomplete.close(); autocomplete.autocomplete.open(); } } ); } ); var algoliaPoweredLink = document.querySelector( '.algolia-powered-by-link' ); if ( algoliaPoweredLink ) { algoliaPoweredLink.addEventListener( 'click', function( e ) { e.preventDefault(); window.location = "https://www.algolia.com/?utm_source=WordPress&utm_medium=extension&utm_content=" + window.location.hostname + "&utm_campaign=poweredby"; } ); } }); </script> <link data-minify="1" rel='stylesheet' id='multiple-authors-widget-css-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/publishpress-authors-pro/lib/vendor/publishpress/publishpress-authors/src/assets/css/multiple-authors-widget.css?ver=1732535982' type='text/css' media='all' /> <style id='multiple-authors-widget-css-inline-css' type='text/css'> :root { --ppa-color-scheme: #655997; --ppa-color-scheme-active: #514779; } </style> <link data-minify="1" rel='stylesheet' id='mailpoet_public-css' href='https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/mailpoet/assets/dist/css/mailpoet-public.2e4711f8.css?ver=1732535971' type='text/css' media='all' /> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/duracelltomi-google-tag-manager/dist/js/gtm4wp-form-move-tracker.js?ver=1732535971" id="gtm4wp-form-move-tracker-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" id="rocket-browser-checker-js-after"> /* <![CDATA[ */ "use strict";var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||!1,descriptor.configurable=!0,"value"in descriptor&&(descriptor.writable=!0),Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){return protoProps&&defineProperties(Constructor.prototype,protoProps),staticProps&&defineProperties(Constructor,staticProps),Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}var RocketBrowserCompatibilityChecker=function(){function RocketBrowserCompatibilityChecker(options){_classCallCheck(this,RocketBrowserCompatibilityChecker),this.passiveSupported=!1,this._checkPassiveOption(this),this.options=!!this.passiveSupported&&options}return _createClass(RocketBrowserCompatibilityChecker,[{key:"_checkPassiveOption",value:function(self){try{var options={get passive(){return!(self.passiveSupported=!0)}};window.addEventListener("test",null,options),window.removeEventListener("test",null,options)}catch(err){self.passiveSupported=!1}}},{key:"initRequestIdleCallback",value:function(){!1 in window&&(window.requestIdleCallback=function(cb){var start=Date.now();return setTimeout(function(){cb({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-start))}})},1)}),!1 in window&&(window.cancelIdleCallback=function(id){return clearTimeout(id)})}},{key:"isDataSaverModeOn",value:function(){return"connection"in navigator&&!0===navigator.connection.saveData}},{key:"supportsLinkPrefetch",value:function(){var elem=document.createElement("link");return elem.relList&&elem.relList.supports&&elem.relList.supports("prefetch")&&window.IntersectionObserver&&"isIntersecting"in IntersectionObserverEntry.prototype}},{key:"isSlowConnection",value:function(){return"connection"in navigator&&"effectiveType"in navigator.connection&&("2g"===navigator.connection.effectiveType||"slow-2g"===navigator.connection.effectiveType)}}]),RocketBrowserCompatibilityChecker}(); /* ]]> */ </script> <script type="text/javascript" id="rocket-preload-links-js-extra"> /* <![CDATA[ */ var RocketPreloadLinksConfig = {"excludeUris":"\/(?:.+\/)?feed(?:\/(?:.+\/?)?)?$|\/(?:.+\/)?embed\/|http:\/\/(\/%5B\/%5D+)?\/(index.php\/)?(.*)wp-json(\/.*|$)|\/refer\/|\/go\/|\/recommend\/|\/recommends\/","usesTrailingSlash":"1","imageExt":"jpg|jpeg|gif|png|tiff|bmp|webp|avif|pdf|doc|docx|xls|xlsx|php","fileExt":"jpg|jpeg|gif|png|tiff|bmp|webp|avif|pdf|doc|docx|xls|xlsx|php|html|htm","siteUrl":"https:\/\/www.couchbase.com\/blog","onHoverDelay":"100","rateThrottle":"3"}; /* ]]> */ </script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" id="rocket-preload-links-js-after"> /* <![CDATA[ */ (function() { "use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e=function(){function i(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(e,t,n){return t&&i(e.prototype,t),n&&i(e,n),e}}();function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var t=function(){function n(e,t){i(this,n),this.browser=e,this.config=t,this.options=this.browser.options,this.prefetched=new Set,this.eventTime=null,this.threshold=1111,this.numOnHover=0}return e(n,[{key:"init",value:function(){!this.browser.supportsLinkPrefetch()||this.browser.isDataSaverModeOn()||this.browser.isSlowConnection()||(this.regex={excludeUris:RegExp(this.config.excludeUris,"i"),images:RegExp(".("+this.config.imageExt+")$","i"),fileExt:RegExp(".("+this.config.fileExt+")$","i")},this._initListeners(this))}},{key:"_initListeners",value:function(e){-1<this.config.onHoverDelay&&document.addEventListener("mouseover",e.listener.bind(e),e.listenerOptions),document.addEventListener("mousedown",e.listener.bind(e),e.listenerOptions),document.addEventListener("touchstart",e.listener.bind(e),e.listenerOptions)}},{key:"listener",value:function(e){var t=e.target.closest("a"),n=this._prepareUrl(t);if(null!==n)switch(e.type){case"mousedown":case"touchstart":this._addPrefetchLink(n);break;case"mouseover":this._earlyPrefetch(t,n,"mouseout")}}},{key:"_earlyPrefetch",value:function(t,e,n){var i=this,r=setTimeout(function(){if(r=null,0===i.numOnHover)setTimeout(function(){return i.numOnHover=0},1e3);else if(i.numOnHover>i.config.rateThrottle)return;i.numOnHover++,i._addPrefetchLink(e)},this.config.onHoverDelay);t.addEventListener(n,function e(){t.removeEventListener(n,e,{passive:!0}),null!==r&&(clearTimeout(r),r=null)},{passive:!0})}},{key:"_addPrefetchLink",value:function(i){return this.prefetched.add(i.href),new Promise(function(e,t){var n=document.createElement("link");n.rel="prefetch",n.href=i.href,n.onload=e,n.onerror=t,document.head.appendChild(n)}).catch(function(){})}},{key:"_prepareUrl",value:function(e){if(null===e||"object"!==(void 0===e?"undefined":r(e))||!1 in e||-1===["http:","https:"].indexOf(e.protocol))return null;var t=e.href.substring(0,this.config.siteUrl.length),n=this._getPathname(e.href,t),i={original:e.href,protocol:e.protocol,origin:t,pathname:n,href:t+n};return this._isLinkOk(i)?i:null}},{key:"_getPathname",value:function(e,t){var n=t?e.substring(this.config.siteUrl.length):e;return n.startsWith("/")||(n="/"+n),this._shouldAddTrailingSlash(n)?n+"/":n}},{key:"_shouldAddTrailingSlash",value:function(e){return this.config.usesTrailingSlash&&!e.endsWith("/")&&!this.regex.fileExt.test(e)}},{key:"_isLinkOk",value:function(e){return null!==e&&"object"===(void 0===e?"undefined":r(e))&&(!this.prefetched.has(e.href)&&e.origin===this.config.siteUrl&&-1===e.href.indexOf("?")&&-1===e.href.indexOf("#")&&!this.regex.excludeUris.test(e.href)&&!this.regex.images.test(e.href))}}],[{key:"run",value:function(){"undefined"!=typeof RocketPreloadLinksConfig&&new n(new RocketBrowserCompatibilityChecker({capture:!0,passive:!0}),RocketPreloadLinksConfig).init()}}]),n}();t.run(); }()); /* ]]> */ </script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/lib/hoverIntent.js?ver=1732535971" id="hoverintent-plugin-js-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/lib/megamenu-plugin.js?ver=1732535971" id="megamenu-plugin-js-js"></script> <script type="text/javascript" id="couchbase-scripts-widgets-js-extra"> /* <![CDATA[ */ var cbWidgets = {"showMore":"Show More","showLess":"Show Less","baseUrlweb":"https:\/\/www.couchbase.com\/blog\/wp-content\/themes\/couchbase","ajaxurl":"https:\/\/www.couchbase.com\/blog\/wp-admin\/admin-ajax.php","algoliaprefix":"newprod_","algoliaAppID":"NI1G57N08Q","algoliaApiKEY":"bb034b12a2bc82fa014ed7e697159e3f","homeUrl":"","load_fixed":"true","website":"searchable_posts"}; /* ]]> */ </script> <script data-minify="1" type="text/javascript" src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/widgets.js?ver=1732535971" id="couchbase-scripts-widgets-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/js/jquery.fitvids.js?ver=1732535971" id="fitVids-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/js/jquery.touchSwipe.js?ver=1732535971" id="touchSwipe-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/js/headroom.js?ver=1732535971" id="headroom-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/paperback/js/jQuery.headroom.js?ver=1732535971" id="headroom-jquery-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-includes/js/comment-reply.min.js?ver=6.6.1" id="comment-reply-js" async="async" data-wp-strategy="async"></script> <script type="text/javascript" id="thickbox-js-extra"> /* <![CDATA[ */ var thickboxL10n = {"next":"Next >","prev":"< Prev","image":"Image","of":"of","close":"Close","noiframes":"This feature requires inline frames. You have iframes disabled or your browser does not support them.","loadingAnimation":"https:\/\/www.couchbase.com\/blog\/wp-includes\/js\/thickbox\/loadingAnimation.gif"}; /* ]]> */ </script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-includes/js/thickbox/thickbox.js?ver=1732535971" id="thickbox-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/heateor-social-login/public/js/heateor-social-login-public.js?ver=1732535971" id="heateor-social-login-public-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" id="heateor_sss_sharing_js-js-before"> /* <![CDATA[ */ function heateorSssLoadEvent(e) {var t=window.onload;if (typeof window.onload!="function") {window.onload=e}else{window.onload=function() {t();e()}}}; var heateorSssSharingAjaxUrl = 'https://www.couchbase.com/blog/wp-admin/admin-ajax.php', heateorSssCloseIconPath = 'https://www.couchbase.com/blog/wp-content/plugins/sassy-social-share/public/../images/close.png', heateorSssPluginIconPath = 'https://www.couchbase.com/blog/wp-content/plugins/sassy-social-share/public/../images/logo.png', heateorSssHorizontalSharingCountEnable = 0, heateorSssVerticalSharingCountEnable = 0, heateorSssSharingOffset = -10; var heateorSssMobileStickySharingEnabled = 1;var heateorSssCopyLinkMessage = "Link copied.";var heateorSssUrlCountFetched = [], heateorSssSharesText = 'Shares', heateorSssShareText = 'Share';function heateorSssPopup(e) {window.open(e,"popUpWindow","height=400,width=600,left=400,top=100,resizable,scrollbars,toolbar=0,personalbar=0,menubar=no,location=no,directories=no,status")} /* ]]> */ </script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/sassy-social-share/public/js/sassy-social-share-public.js?ver=1732535971" id="heateor_sss_sharing_js-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-includes/js/underscore.min.js?ver=1.13.4" id="underscore-js"></script> <script type="text/javascript" id="wp-util-js-extra"> /* <![CDATA[ */ var _wpUtilSettings = {"ajax":{"url":"\/blog\/wp-admin\/admin-ajax.php"}}; /* ]]> */ </script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-includes/js/wp-util.min.js?ver=6.6.1" id="wp-util-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/wp-search-with-algolia/js/algoliasearch/dist/algoliasearch-lite.umd.js?ver=1732535971" id="algolia-search-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/plugins/wp-search-with-algolia/js/autocomplete.js/dist/autocomplete.min.js?ver=2.8.1" id="algolia-autocomplete-js"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/wp-search-with-algolia/js/autocomplete-noconflict.js?ver=1732535971" id="algolia-autocomplete-noconflict-js"></script> <script type="rocketlazyloadscript" data-rocket-type="text/javascript" data-rocket-src="https://www.google.com/recaptcha/api.js?render=explicit&ver=6.6.1" id="mailpoet_recaptcha-js"></script> <script type="text/javascript" id="mailpoet_public-js-extra"> /* <![CDATA[ */ var MailPoetForm = {"ajax_url":"https:\/\/www.couchbase.com\/blog\/wp-admin\/admin-ajax.php","is_rtl":"","ajax_common_error_message":"An error has happened while performing a request, please try again later."}; /* ]]> */ </script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-type="text/javascript" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/plugins/mailpoet/assets/dist/js/public.js?ver=1732535971" id="mailpoet_public-js" defer="defer" data-wp-strategy="defer"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/npm/algoliasearch@4.22.1/dist/algoliasearch-lite.umd.js?ver=1732535971"></script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/npm/instantsearch.js@4.64.0/dist/instantsearch.production.min.js?ver=1732535971"></script> <script type="rocketlazyloadscript" data-rocket-src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js"></script> <script type="rocketlazyloadscript"> const { autocomplete,getAlgoliaResults, getAlgoliaFacets } = window['@algolia/autocomplete-js']; </script> <script type="rocketlazyloadscript" data-minify="1" data-rocket-src="https://www.couchbase.com/blog/wp-content/cache/min/1/blog/wp-content/themes/couchbase/js/algo-search.js?ver=1732535971"></script> <script>var rocket_beacon_data = {"ajax_url":"https:\/\/www.couchbase.com\/blog\/wp-admin\/admin-ajax.php","nonce":"67f52ba07d","url":"https:\/\/www.couchbase.com\/blog\/recursive-query-processing-in-sql-n1ql","is_mobile":false,"width_threshold":1600,"height_threshold":700,"delay":500,"debug":null,"status":{"atf":true,"lrc":true},"elements":"img, video, picture, p, main, div, li, svg, section, header, span","lrc_threshold":1800}</script><script data-name="wpr-wpr-beacon" src='https://www.couchbase.com/blog/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js' async></script></body> </html> <!-- This website is like a Rocket, isn't it? Performance optimized by WP Rocket. Learn more: https://wp-rocket.me -->