Function: genericRename

    +

    Goal: Recursively and Generically Rename Keys in a document.

    • This function genericRename shows how a document can have its keys or fields renamed.

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

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

    • 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 transformed 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_rename:".

    • genericRename

    • Input Data/Mutation

    • Output Data/Mutation

    // To run configure the settings for this Function, genericRename, 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 renamePartsByMap(obj, rename_map) {
        if (obj !== null && typeof obj == "object") {
            Object.entries(obj).forEach(([k, v]) => {
                if (obj[k] && typeof obj[k] === 'object') {
                    // recurse
                    renamePartsByMap(obj[k], rename_map)
                }
                if (obj[k]) {
                    // recurse
                    var tst = rename_map[k];
                    if (tst) {
                        if (tst !== undefined && tst !== null) {
                            obj[rename_map[k]] = obj[k];
                            delete(obj[k]);
                        }
                    }
                }
            });
        }
        return obj;
    }
    
    function OnUpdate(doc, meta) {
        if (doc.type !== "my_data_to_rename") return;
    
        // rename long fields to shorter names using a MAP
        var rename_map = {
            "a_first_super_long_name_right_here": "a_short1",
            "a_second_super_long_name_right_here": "a_short2",
            "a_third_super_long_name_right_here": "a_short3"
        };
        var newdoc = renamePartsByMap(doc, rename_map);
    
        // alias dst_col to our source collection. Since rev 6.5+ allowed to be in r/w mode
        dst_col[meta.id] = newdoc;
    }
    
    function OnDelete(meta, options) {
        // filter
        if (!(meta.id.startsWith("my_data_to_rename:"))) 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);
        }
    }
    INPUT: KEY my_data_to_rename::1001
    
    {
      "type": "my_data_to_rename",
      "id": 1001,
      "a_first_super_long_name_right_here": 111,
      "b": "my object",
      "c": "",
      "d": null,
      "f": {
        "m": {
          "a": "asd"
        }
      },
      "f2": {
        "m": {
          "a": "asd",
          "a_second_super_long_name_right_here": 222,
          "ary1": [
            {
              "a_second_super_long_name_right_here": 1
            },
            {
              "a_second_super_long_name_right_here": 2
            },
            [
              {
                "a_second_super_long_name_right_here": 1
              },
              {
                "a_second_super_long_name_right_here": 2
              }
            ]
          ]
        }
      },
      "a_third_super_long_name_right_here": {
        "x": 1,
        "y": 2,
        "not_a_key_will_not_change": "a_third_super_long_name_right_here"
      }
    }
    UPDATED/OUTPUT: KEY my_data_to_rename::1001
    
    {
      "type": "my_data_to_rename",
      "id": 1001,
      "b": "my object",
      "c": "",
      "d": null,
      "f": {
        "m": {
          "a": "asd"
        }
      },
      "f2": {
        "m": {
          "a": "asd",
          "ary1": [
            {
              "a_short2": 1
            },
            {
              "a_short2": 2
            },
            [
              {
                "a_short2": 1
              },
              {
                "a_short2": 2
              }
            ]
          ],
          "a_short2": 222
        }
      },
      "a_short1": 111,
      "a_short3": {
        "x": 1,
        "y": 2,
        "not_a_key_will_not_change": "a_third_super_long_name_right_here"
      }
    }