Upsert Type Coercion

#1

So we have the following tree for our types:

     B
   /   \
  S     P

Where S & P both mix B and introduce no new fields except entity. So S & P are distinct Types on distinct tables and this must remain true.

We need to upsert/copy S to P as smoothly as possible when a function is called. How should I go about coercing the S type into the P type without losing data?

0 Likes

#2

Once an instance is instantiated, it is tagged with its type. You can get the bare values using JSON.stringify and then re-make as the other type. The only trick is that part of the serialized form is the type name, so that needs to be removed. So let’s say you have an instance of S that you want to save as an instance of P:

  var theS = ...;
  var json = JSON.parse(JSON.stringify(theS));
  delete json.type;
  var theP = P.make(json);

This is just to give you an idea of how to un-make and re-make objects. The flow within your application may admit of a more concise solution.

0 Likes

#3

If you want to move ALL fields (of all objects) from theS to theP, your code could look like

var p;
SType.fetchObjStream({include:"this"}).each(function(s) {
  p = P.make(JSON.parse(JSON.stringify(s)))
  delete p.type;
  p.upsert();
})

fetching with “this” will include all fields of P. You would probably want to add some batching logic to the above to avoid upserting each individual P one at a time.

0 Likes

#4

So I got a solution working, this was very helpful, thank you! So my followup question is how I can use map instead of each, when I use map it doesn’t seem to get invoked and so I am not sure what I need to do in order to get it operational.

So in this example I used map instead of each, but it doesn’t get invoked:

var p;
SType.fetchObjStream({include:"this"}).map(function(s) {
  p = P.make(JSON.parse(JSON.stringify(s)))
  delete p.type;
  p.upsert();
})
0 Likes

#5

So correction,
I talked with Bus for a moment and map isn’t going to do what I want it to as the map operation is still single threaded. What I want is a batch process that the MapReduce system processes in parallel. I am currently looking into that, but any advice about how this could be adapted would be much appreciated.

0 Likes

#6

Consider writing a MapReduce job

entity type MapReduce<Extractable, Void, Void, Void>

function map(objs) {
newObjs = []
objs.each(function(o) {
p = P.make(JSON.parse(JSON.stringify(o)))
delete p.type;
newObjs.push§
})
P.upsertBatch(newObjs)
}

0 Likes

#7

@JohnCoker @rileysiebel
Would that make sense to add a member function called unmake() ?

0 Likes