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);
          }
      }

      in keyspace bulk.data.source

      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"
        }
      }

      in keyspace bulk.data.destination

      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"
        }
      }