0

I am working with NodeJS on Google App Engine with the Datastore database.

Note that this question is an extension of (not a duplicate) my original post.

Due to the fact that Datastore does not have support the OR operator, I need to run multiple queries and combine the results.

Here is my approach (based on the selected answer from my original post):

  1. Use Keys-only queries in the 1st stage
  2. Perform the combination of the keys obtained into a single list (including deduplication)
  3. Obtaining the entities simply by key lookup

I have achieved #1 by running two separate queries with the async parallel module. I need help with step 2.

Question: How to combine (union) two lists of entity keys into a single list (including de-duplication) efficiently?

The code I have below successfully performs both the queries and returns two objects getEntities.requesterEntities and getEntities.dataownerEntities.

//Requirement: Get entities for Transfer Requests that match either the Requester OR the Dataowner

  async.parallel({
    requesterEntities: function(callback) {
      getEntitiesByUsername('TransferRequest', 'requester_username', loggedin_username, (treqs_by_requester) => {
        //Callback pass in response as parameter
        callback(null, treqs_by_requester)
      });
    },
    dataownerEntities: function(callback) {
      getEntitiesByUsername('TransferRequest', 'dataowner_username', loggedin_username, (treqs_by_dataowner) => {
        //Callback pass in response as parameter
        callback(null, treqs_by_dataowner)
      });
    }
  }, function(err, getEntities) {
    console.log(getEntities.requesterEntities);
    console.log(getEntities.dataownerEntities);

    //***HOW TO COMBINE (UNION) BOTH OBJECTS CONTAINING DATASTORE KEYS?***//

  });

function getEntitiesByUsername(kind, property_type, loggedin_username, getEntitiesCallback) {
  //Create datastore query
  const treq_history = datastore.createQuery(kind);
  //Set query conditions
  treq_history.filter(property_type, loggedin_username);
  treq_history.select('__key__');

  //Run datastore query
  datastore.runQuery(treq_history, function(err, entities) {
    if(err) {
      console.log('Transfer Request History JSON unable to return data results for Transfer Request. Error message: ', err);
    } else {
      getEntitiesCallback(entities);
    }
  });
}
pengz
  • 2,279
  • 3
  • 48
  • 91

1 Answers1

0

I was able to combine the two separate sets of entity keys by iterating over the arrays and comparing the ID values for each entity key and creating a new array with the unique keys.

Note: The complete solution is posted as an answer to my original post.

//Union of two arrays of objects entity keys
function unionEntityKeys(arr1, arr2) {
  var arr3 = [];
  for(var i in arr1) {
    var shared = false;
      for (var j in arr2)
        if (arr2[j][datastore.KEY]['id'] == arr1[i][datastore.KEY]['id']) {
          shared = true;
          break;
        }
      if(!shared) {
        arr3.push(arr1[i])
      }
    }
  arr3 = arr3.concat(arr2);
  return arr3;
}
pengz
  • 2,279
  • 3
  • 48
  • 91