JavaScript Functions with Couchbase

    +
    Writing Couchbase Server extension functions in the JavaScript Language.

    Introduction

    N1QL includes a large number of operations and generic functions that cover every aspect of data manipulation. In addition to the built-in functions, Couchbase also allows you to create your own extensions to the language.

    Using User-Defined Functions, you can:

    • Create reuseable, domain-specific functions for use in your applications.

    • Execute complex logic that may be difficult to do in N1QL.

    • Migrate from RDBMS stored procedures.

    If you want to learn how to create JavaScript function libraries using the administration console and/or the REST-API then take a look at our JavaScript UDF Guides.

    Added Constructs

    Javascript functions in Couchbase support most of the language constructs available in ECMAScript, though there are a number of restrictions related to the Couchbase environment. There are also additions that have been made to the language for working specifically with Couchbase.

    N1QL Embedded Statements

    Top level N1QL keywords, such as SELECT, UPDATE, INSERT and DELETE, are available as inline keywords in functions. Operations that return values such as SELECT are accessible through a returned iterable handle. N1QL Query results, via a SELECT, are streamed in batches to the iterable handle as the iteration progresses through the result set.

    function selectAirline(country) {
    
        var q = SELECT name as airline_name, callsign as airline_callsign 
        FROM `travel-sample`.`inventory`.`airline` 
        WHERE country = $country;  (1)
    
        var res = [];
    
        for (const doc of q) {
    
            var airline = {}
            airline.name = doc.airline_name  (2)
            airline.callsign = doc.airline_callsign  (2)
            res.push(airline);
    
        }
    
        return res;
    
    }
    1 The N1QL is written directly into the JavaScript code without having to be used as part of a function call. We can even provide parameters that can be used in the N1QL statement.
    2 A standard JavaScript iterator is used to access the values returned from the N1QL statement.

    Libraries and Scopes

    JavaScript functions are stored inside a library. A library can contain one or more functions, and can also be assigned to a scope which allows libraries to be partitioned for logical grouping.

    Javascript UDFs Structure
    Figure 1. Javascript UDFs Structure

    As shown in Figure 1, a JavaScript function library can exist as:

    • A global library accessible across the cluster.

    • A library accessible within a scope.

    You can find an introduction to scopes in our Couchbase Tutorials

    Furthermore, access restrictions can be applied to scopes, so that only certain groups of users will be able to access collections and libraries within that scope.

    Scopes for JavaScript Libraries
    Figure 2. Scopes for JavaScript Libraries

    The user does not call a JavaScript function (shown here as getBusinessDays(startDate, endDate)) directly; a N1QL User-Defined Function is defined to act a reference caller to the JavaScript function.

    In Couchbase terminology, you would set the user’s context to travel-sample.inventory in order for him/her to run the functions in my-library.

    Unsupported Features

    Browser Extensions

    Because JavaScript UDF functions do not execute in the context of a browser, the extensions that browsers add to the core language, such as window methods, DOM events etc. are not available.

    Global State

    All variables must be local to the function; global state is not permitted.

    var count = 0;                         // Not allowed - global variable.
    function increment() {
        count++;
    }

    Along with global state, global arrow functions are not supported. Arrow functions local to individual javascript functions are supported.

    Logging

    Logging using the console.log(..) function is not supported.

    In the rest of this section, we’re going to look at the concepts behind JavaScript User-Defined Functions: