Parse Query overrides new query over old one?

#1

I’m doing parse query to get data but new query parameter overrides old one.

In my app user can block other users. When its done I write a “Block” object to database like this

I block other user:

ParseObject block = new ParseObject("Block");                                
block.put("owner",ParseUser.getCurrentUser());                                                
block.put("who",otherUser);

when I get data I use this query.

    //I blocked him. dont sow me his data.
    ParseQuery<ParseObject> benblock= new ParseQuery<ParseObject>("Block");
    benblock.whereEqualTo("owner", ParseUser.getCurrentUser());
    
    //He blocked me dont show me his data.
    ParseQuery<ParseObject> oblock = new ParseQuery<ParseObject>("Block");                  
    oblock.whereEqualTo("who",ParseUser.getCurrentUser());
                   
    query.whereDoesNotMatchKeyInQuery("user","owner",oblock);    //This line doesn't work              
    query.whereDoesNotMatchKeyInQuery("user","who",benblock); //But this line does

But when i retrieve data first query option

query.whereDoesNotMatchKeyInQuery("user","owner",oblock); 

doesnt work only last one

 query.whereDoesNotMatchKeyInQuery("user","who",benblock);

works. How can I fix this?

Stackoverflow question: https://stackoverflow.com/questions/56098553/parse-query-overrides-new-query-over-old-one

#2

Just answered you in Stackoverflow. Basically, you can’t add two of the same constraint for the same key. You will need to use Parse.Query.and to combine both queries.

1 Like
#3

Android sdk doesn’t have “and” condition. Is there any other way?

Docs says:

You can add additional constraints to the newly created ParseQuery that act as an ‘and’ operator.

What does this mean. My english is not enough to understand this.

Edit:
I think I solved with this code. I edit this post if it success.

Edit2: This code doesnt work

ParseQuery<ParseObject> oblock = new ParseQuery<ParseObject>("Block");
        oblock.whereEqualTo("who",ParseUser.getCurrentUser());
        hashtag1.whereDoesNotMatchKeyInQuery("user","owner",oblock);
        
        List<ParseQuery<ParseObject>> querylist = new ArrayList<>();
        querylist.add(hashtag1);
        
        ParseQuery<ParseObject> benblock= new ParseQuery<ParseObject>("Block");
        benblock.whereEqualTo("owner", ParseUser.getCurrentUser());
        ParseQuery<ParseObject> query = ParseQuery.or(querylist);
        query.whereDoesNotMatchKeyInQuery("user","who",benblock);
#4

Sorry. I haven’t noticed. I’ve just updated the answer. Can you please try the new version?

#5

Doesn’t work. Query still retrieve blocked persons data. Also seems like I cant set limit or get relational data with include method.

#6

I solved my issue by doing this.

According to this(https://github.com/parse-community/Parse-SDK-Android/issues/211#issuecomment-150047052) Parse query override whereDoesNotMatchKeyInQuery only for the same key. Which meand I can use that parameter twice in a same query but not same key. And I just created same value with different key.

Previous my object was like this

        ParseObject object = new ParseObject("DataClass");
        object.put("post",post);
        object.put("user",user);

Now It looks like this:

        ParseObject object = new ParseObject("DataClass");
        object.put("post",post);
        object.put("user",user);
        object.put("user2",user);//same user with the above one

And I do query like this:

    ParseQuery<ParseObject> benblock= new ParseQuery<ParseObject>("Block");
    benblock.whereEqualTo("owner", ParseUser.getCurrentUser());

    ParseQuery<ParseObject> oblock = new ParseQuery<ParseObject>("Block");
    oblock.whereEqualTo("who",ParseUser.getCurrentUser());

    hashtag.whereDoesNotMatchKeyInQuery("user","owner",oblock);
    hashtag.whereDoesNotMatchKeyInQuery("user2","who",benblock);

With this way It consumes more space but I’m able to get what I want. And thats the important thing right? Also I was out of ideas.

#7

I’d say it is not the best solution, but it works :slight_smile:

If you want, post your updated code (after my suggestions) in Stackoverflow and I will try to help to figure it out.

#8

I don’t think I understand what you meant because my poor English skills.
I’ve already posted this code on stackoverflow. If you have better solution I will use it gladly. I’m doing this way because nothing else come to my mind. I was out of ideas. :slight_smile:

1 Like
#9

Do you think this is an efficient query?

While I searching about parse queries I found out in this page that I must avoid using parameters like “notEqualto” or “NotContainedin” etc…

and my query has “whereDoesNotMatchKeyInQuery” twice.

This is my full query.

     ParseQuery<ParseObject> hashtag = new ParseQuery<ParseObject>("Hashtag");

     ParseQuery<ParseObject> benblock= new ParseQuery<ParseObject>("Block");
     benblock.whereEqualTo("owner", ParseUser.getCurrentUser());

    ParseQuery<ParseObject> oblock = new ParseQuery<ParseObject>("Block");
    oblock.whereEqualTo("who",ParseUser.getCurrentUser());

    hashtag.whereDoesNotMatchKeyInQuery("user","owner",oblock);
    hashtag.whereDoesNotMatchKeyInQuery("user2","who",benblock);

   hashtag.whereEqualTo("hashtag",getIntent().getExtras().getString("url"));
   hashtag.setLimit(30);
   hashtag.include("post.user");
   hashtag.orderByDescending("createdAt");
   hashtag.whereLessThan("createdAt",objectlist.get(objectlist.size()-1).getCreatedAt());

Do you think this is an efficient query? What are the results if this query run on a large scale database? My collections are indexed.

Edit: According to docs (If I understand correctly) whereDoesNotMatchKeyInQuery parameter can’t use indexes. That means Mongo has to chech every item. What are your suggestions on that? Seems like parse dont have a replacement query for what I need. Should I keep using or what?

#10

The way you solved is little bit weird because you had to duplicate the user field, but in terms of performance I think you should be fine. Creating { owner: 1 } and { who: 1 } indexes at Block collection and a { hashTag: 1, user: 1, user2: 1, _created_at: -1 } index at Hashtag should give you a good performance.

1 Like