11

I'm trying to find users I didn't connect to before with a cloud function. There are few tables I'm using:

  1. Users table - The standard table with an added "hasLight" boolean column
  2. Connected table:
    • 'user' - pointer to the user (first side)
    • 'userId' - objectId of the user
    • 'user2' - pointer to the user we connect with
    • 'userId2' - objectId of the user we connected to
  3. Available table:
    • 'userObjectId' - objectId of the user
    • 'counter' - number

The code:

Parse.Cloud.define("findFreshUser", function(request, response) {

    Parse.Cloud.useMasterKey(); // For reading all the table //

    var user = Parse.User.current();

    // Get all possible users we already connected to //
    var connectQuery = new Parse.Query("Connected");
    connectQuery.include('userId2');
    connectQuery.equalTo("userId", Parse.User.current().id);

    // Get all users with availability of '0' //
    var availableQuery = new Parse.Query("Available");
    availableQuery.notEqualTo("counter", 0);  

    var freshUserQuery = new Parse.Query(Parse.User);

    freshUserQuery.doesNotMatchKeyInQuery("objectId", "userId2", connectQuery); // We haven't connected before - THIS DOEN'T WORK !!! //
    freshUserQuery.doesNotMatchKeyInQuery("objectId", "userObjectId", availableQuery); // We won't use '0' availability users - THIS WORKS //

    freshUserQuery.equalTo("hasLight", false); // user must not have a light //
    freshUserQuery.descending("updatedAt");
    freshUserQuery.limit(1); // We need only 1 user //

    freshUserQuery.find({ 
        success: function(results) {
            if (results.length>0){
                console.log("Found the user "+ results[0].id);
                response.success(results[0].id);
            }else{
                response.error("No user found");
            }

        },
        error: function() {
            response.error("No user found");
        }
    });

});

For some reason CloudCode completely ignoring connectQuery (all other statements are fine) when using 2 doesNotMatchKeyInQuery statements:

When using only

freshUserQuery.doesNotMatchKeyInQuery("objectId", "userId2", connectQuery);

and comment out

freshUserQuery.doesNotMatchKeyInQuery("objectId", "userObjectId", availableQuery);

it does work. So I think it is related to using both at same time, they are probably conflicting each other. What do I need to do to make both apply?

It feels like it's some parse issue but I'm really new to CloudCode so it's probably something I'm not doing right.

Note: Pay attention that I even don't compare the user object itself but the id of it (this is as part of isolating the issue). Means, I know I could make the code and DB lots nicer.

Idan
  • 9,880
  • 10
  • 47
  • 76
  • 1
    The root issue here is that freshUserQuery.doesNotMatchKeyInQuery("objectId", "userId2", connectQuery); conflicts with freshUserQuery.doesNotMatchKeyInQuery("objectId", "userObjectId", availableQuery); The query only supports one of each constraint per key, so the second one is overwriting the first. Leaving this open to be answered by someone who wants to aid in rewriting the query and/or using promises to do this using several queries. – Héctor Ramos Aug 07 '15 at 21:22
  • @HectorRamos Btw, I haven't seen this restriction on your docs. Maybe you should consider refresh that or make it more clear with this point. – Idan Aug 08 '15 at 09:44
  • @HectorRamos Seems no one knows how to do it. You can answer and get the bounty points. – Idan Aug 11 '15 at 08:16
  • Honestly, I would re-think the schema. Relying heavily on notEqualTo and other similar constraints is not recommended at scale. It's best if you request what you want, as opposed to what you do not want, for example. See http://blog.parse.com/learn/engineering/efficient-parse-queries/ and http://blog.parse.com/videos/f8-2015-running-at-scale/ – Héctor Ramos Aug 11 '15 at 23:53
  • @HectorRamos I want all counter values that are more (not equal) to '0'. For some cases I could use equalTo. But what about when I want an integer to be more than '0'? – Idan Sep 07 '15 at 14:30

1 Answers1

-2

You have to use Promise to achieve such query : blog.parse.com/learn/engineering/whats-so-great-about-javascript-promises/

Toucouleur
  • 1,194
  • 1
  • 10
  • 30
  • I tried several methods using promise to achieve the result but to my understanding this should be execute as a single query (only a single find). Maybe you could help me with an example on my code. I just can't figure this out myself. – Idan Aug 05 '15 at 13:43