Function: Advanced Self-Recursion Parameter

    February 16, 2025
    + 12

    Perform the Advanced Self-Recursion parameter where Eventing interacts with the Data Service.

    The advancedSelfRecursion function:

    • Performs the Advanced Self-Recursion parameter

    • Requires Eventing Storage (or a metadata collection) and a source collection

    • Requires a binding of type bucket alias

    • Operates on any mutation where the meta.id or KEY starts with doquery:

    For more information about the Advanced Self-Recursion parameter, see Optional { "self_recursion": true }` Parameter.

    The following example shows you how to stop and restart a long-running process like a N1QL query. It counts the number of hotels that start with a particular letter.

    javascript
    // Configure the settings for the advancedSelfRecursion function as follows: // // Version 7.6+ // "Function Scope" // *.* (or try bulk.data if non-privileged) // "Listen to Location" // bulk.data.source // "Eventing Storage" // rr100.eventing.metadata // Binding(s) // 1. "binding type", "alias name...", "bucket.scope.collection", "Access" // "bucket alias", "src_col", "bulk.data.source", "read and write" // // You must have the sample dataset travel-sample installed function OnUpdate(doc, meta) { if ( meta.id.startsWith("doquery:") === false ) return; if (doc.done && doc.done === true) return; if (! doc.continue) { doc.queryBeg = new Date(); doc.queryCnt = 0; doc.currentQueryOffset = 0; doc.namesProcessed = 0; doc.letterHash = {}; log(meta.id,'Query initialized at ' + doc.queryBeg); } var offset = doc.currentQueryOffset; var results = SELECT name FROM `travel-sample`.`inventory`.`hotel` LIMIT 100 OFFSET $offset; doc.queryCnt++; doc.currentQueryOffset = doc.currentQueryOffset + 100; var loopCnt = 0; for (var item of results) { loopCnt++; doc.namesProcessed++; var name = item.name; if (name && name.length > 0) { // Extract the first character and convert it to lowercase var firstChar = name[0].toLowerCase(); // If the letter exists in the hash, increment its count. Otherwise initialize it to 1. if (doc.letterHash[firstChar]) { doc.letterHash[firstChar]++; } else { doc.letterHash[firstChar] = 1; } } } results.close(); if (loopCnt < 100) { // we are done if (doc.continue) delete doc.continue doc.done = true; doc.queryEnd = new Date(); log(meta.id,'Query cnt complete mutations ' + doc.queryCnt + ' namesProcessed ' + doc.namesProcessed ); log(meta.id,'Query completed at ' + doc.queryEnd); log(meta.id,'Result hotels starting with "a" ' + doc.letterHash['a'] + ', hotels starting with "b" ' + doc.letterHash['b'] + ', ...'); // no self recursion src_col[meta.id] = doc; } else { // we are not done doc.continue = true; log(meta.id,'Query cnt in progress mutations ' + doc.queryCnt + ' namesProcessed ' + doc.namesProcessed ); // using self recursion results in a continuation of the query couchbase.upsert(src_col, meta, doc, { "self_recursion": true }); } }