A newer version of this documentation is available.

View Latest

Function: genericFlatten

    March 23, 2025
    + 12

    Goal: Recursively and Generically Flatten a document for integration with a non-NOSQL RDBMS.

    • This function genericFlatten shows how a document can be flattened into a RDBMS importable record.

    • Requires Eventing Storage (or metadata collection), a "source" collection, and a "destination" collection.

    • Will operate on all documents where doc.type === "my_data_to_flatten".

    • Will write transformed or flattened documents to the destination collection with the same type and id.

    • The destination collection can be shared (or replicated via XCDR to a business partner - maybe to AWS, GCP, or Azure).

    • Will also remove the flattened document in the destination collection when the original source document is removed.

    • Note since the document is not available during an OnDelete we will filter by KEY prefix starting with "my_data_to_flatten:".

    javascript
    // To run configure the settings for this Function, genericFlatten, as follows: // // Version 7.1+ // "Function Scope" // *.* (or try bulk.data if non-privileged) // Version 7.0+ // "Listen to Location" // bulk.data.source // "Eventing Storage" // rr100.eventing.metadata // Binding(s) // 1. "binding type", "alias name...", "bucket.scope.collection", "Access" // "bucket alias", "dst_col", "bulk.data.destination", "read and write" // // Version 6.X // "Source Bucket" // source // "MetaData Bucket" // metadata // Binding(s) // 1. "binding type", "alias name...", "bucket", "Access" // "bucket alias", "dst_col", "destinaton", "read and write" function deepFlatten(obj,flatDoc, path) { if (!obj || typeof obj !== 'object') { // log("terminal", path, obj); // remove leading "_" and store the path as a key to the terminal value flatDoc[path.substr(1)] = obj; return obj; } // process Object let newObj = {}; if (Array.isArray(obj)) { for (var i=0; i<= obj.length; i++ ) { newObj[i] = deepFlatten(obj[i], flatDoc, path + "_" + i) } } else { Object.keys(obj).forEach((k) => { return newObj[k] = deepFlatten(obj[k], flatDoc, path + "_" + k); }) } return newObj; } function OnUpdate(doc, meta) { if (doc.type !== "my_data_to_flatten") return; var flatDoc = {}; deepFlatten(doc,flatDoc,""); // alias src_bkt to our source bucket. Since rev 6.5+ allowed to be in r/w mode dst_col[meta.id] = flatDoc; } function OnDelete(meta, options) { // filter if (!(meta.id.startsWith("my_data_to_flatten:"))) return; log("OnDelete expired=" + options.expired +" REM id: "+meta.id); try { delete dst_col[meta.id]; } catch (e) { log("Error on delete: "+e+", id:",meta.id); } }