Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Q: Parse.com query count stability

For testing purpose I put the following code in the onCreate() of an Activity:

    // Create 50 objects
    for (int i = 0; i < 50; i++) {
        ParseObject obj = new ParseObject("test_obj");
        obj.put("foo", "bar");
        try {
            obj.save();
        } catch (ParseException pe) {
            Log.d("Parsetest", "Failed to save " + pe.toString());
        }
    }

    // Count them
    for (int i = 0; i < 10; i ++) {
        ParseQuery<ParseObject> query = ParseQuery.getQuery("test_obj");
        query.countInBackground(new CountCallback() {
            @Override
            public void done(int count, ParseException e) {
                if (e == null) {
                    Log.d("Parsetest", "Background found " + count + " objects");
                } else {
                    Log.d("Parsetest", "Query issue" + e.toString());
                }
            }
        });
    }

I would expect the count to be always fifty, however running this code yields something like:

D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 50 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects
D/Parsetest(17761): Background found 0 objects

Can somebody explain this behavior and how to correct this ?

like image 890
amo-ej1 Avatar asked Jun 10 '26 23:06

amo-ej1


1 Answers

Without knowing further details, I'm inclined to believe the inconsistency is due to threading and the mixing of synchronous/asynchronous calls.

For example, calling obj.save(); is synchronous (reference), however, without seeing the rest of your code, it's possible that the synchronous save is being executed on a background thread.

Additionally, query.countInBackground is asynchronous and is being called multiple times with a for loop. This is going to simultaneously create 10 separate background processes to query Parse for the count of objects and depending on how the save is handled there could be race conditions.

Lastly, there are documented limitations on count operations with Parse.

Count queries are rate limited to a maximum of 160 requests per minute. They can also return inaccurate results for classes with more than 1,000 objects. Thus, it is preferable to architect your application to avoid this sort of count operation (by using counters, for example.)

From Héctor Ramos on the Parse Developers Google group,

Count queries have always been expensive once you throw some constraints in. If you only care about the total size of the collection, you can run a count query without any constraints and that one should be pretty fast, as getting the total number of records is a different problem than counting how many of these match an arbitrary list of constraints. This is just the reality of working with database systems.

Given the cost of count operations, it is possible that Parse has mechanisms in place to prevent rapid bursts of count operations from a given client.

If you are needing to perform count operations often, the recommended approach is to use cloud code afterSave hooks to increment/decrement a counter as needed.

like image 113
Russell Avatar answered Jun 13 '26 09:06

Russell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!