3

I have a table in my Parse database with columns validFrom and uniqueId. There can be multiple records with the same uniqueId (like a name)

What query do I have to use to get the items with the latest validFrom for a given set of uniqueIds? I tried the following but this limits my search to 1 item for the entire set rather than 1 item per unique_id record:

  var UpdateObject = Parse.Object.extend("UpdateObject");
  var query = new Parse.Query(UpdateObject);
  query.containedIn("unique_id", uniqueIdsArray).select('status', 'unique_id').descending("validFrom").limit(1);
rex
  • 3,133
  • 6
  • 35
  • 62
  • What do you mean "1 item per unique_id record"? – danh Jan 05 '16 at 19:58
  • Ie only the latest record per uniqueId records – rex Jan 05 '16 at 19:59
  • Basically like saying I want the latest value for each record with a certain unique_id and then filter on a certain number of unique ids – rex Jan 05 '16 at 20:00
  • "unique" implies that a given uniqueId corresponds to exactly one object, is that true? – danh Jan 05 '16 at 20:01
  • No multiple objects in the db can have the same unique Id. For example you can have 10 records with unique Id x and different valid from and then another 10 records with unique id y and different valid from – rex Jan 05 '16 at 20:04
  • 1
    Okay. This can be done with a single query, but one that retrieves more than you want. It will require app logic to reduce the result. This is a good application for a cloud function. Should I suggest one? – danh Jan 05 '16 at 20:08
  • Please - I would prefer to minimise client logic and db requests. Not sure how many cloud functions I can use with the free parse package though? Thanks! – rex Jan 05 '16 at 20:10
  • I would be interested to see both solutions – rex Jan 05 '16 at 20:10
  • on a JS client, they are the same, the cloud version just saves you from transmitting objects that the app logic will filter out to get the query result down to just the qualifying set. no limit on number of cloud functions (just max request rate of 30/sec). – danh Jan 05 '16 at 20:12
  • oh great - yes i would be very interseted to see the solution on cloud – rex Jan 05 '16 at 20:17

1 Answers1

1

The query semantics are limited, so the only approach is to query for a superset and manipulate the result to what you need. This is better done on the server to limit the transmission of extra objects.

Big caveat: did this with pencil and paper, not a running parse.app, so it may be wrong. But the big idea is to get all of the matching objects for all of the uniqueIds, group them by uniqueId, and then for each group return the one with the maximum validFrom date...

function updateObjectsInSet(uniqueIdsArray ) {
    var query = new Parse.Query("UpdateObject");
    // find all of the UpdateObjects with the given ids
    query.containedIn("unique_id", uniqueIdsArray);
    query.limit(1000);
    return query.find().then(function(allUpdates) {
        // group the result by id
        var byId = _.groupBy(allUpdates, function(update) { return update.get("unique_id"); });
        // for each group, select the newest validFrom date
        return _.map(byId, function (updates) {  
            _.max(updates, function(update) { return -update.get("validFrom").getTime(); });
        });
    });
}

To place this in the cloud, just wrap it:

Parse.Cloud.define("updateObjectsInSet", function(request, response) {
    updateObjectsInSet(request.params.uniqueIdsArray).then(function(result) {
        response.success(result);
    }, function(error) {
        response.error(error);
    });
});

Then use Parse.Cloud.run() from the client to call it.

danh
  • 62,181
  • 10
  • 95
  • 136
  • ah there is a limit on the initial set that i can get? I'm starting to think that perhaps I should make a new table that always stores the latest record asociated with the each unique-id and replace the values in that table whenever there is an update... – rex Jan 05 '16 at 20:42
  • That wouldn't be a bad idea. The default limit on a query is 100. It can be increased to a max 1k – danh Jan 05 '16 at 20:47
  • Yes i think i will make a new table that points to the latest update and get that updated with a cloud code function. I wasn't aware of the cloud-code functionality! Thanks. I will be marking your answer. Keep your eyes peeled on some more questions re cloud code! haha – rex Jan 05 '16 at 20:49