Parse-server: Interpolate objectId and Pointer (as on parse.com)

Created on 13 Apr 2017  路  36Comments  路  Source: parse-community/parse-server

Issue Description

Like: #1014, matchesKeyInQuery returns an empty set.

The ACL is set correctly, and can query both records separately.

Steps to reproduce

where={
  "season": {
    "$select": {
      "key": "objectId",
      "query": {
        "where": {
          "fullIdentifier": "CD117"
        },
        "className": "Season"
      }
    }
  }
}

Expected Results

The results should be returned

Actual Outcome

An empty set is returned

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : 2.3.6
    • Operating System: OSX 10.12.1
    • Hardware: MBP-2015
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): localhost
  • Database

    • MongoDB version: 3.2.11
    • Storage engine: MMAPv1
    • Hardware: ??
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): mLab

Logs/Trace

REQUEST for [GET] /parse/classes/Fixture?where=%7B%22season%22%3A%7B%22%24select%22%3A%7B%22key%22%3A%22objectId%22%2C%22query%22%3A%7B%22where%22%3A%7B%22fullIdentifier%22%3A%22CD117%22%7D%2C%22className%22%3A%22Season%22%7D%7D%7D%7D&include=home%2ChomeResult%2Chome.club%2Chome.ground%2Caway%2CawayResult%2Caway.club%2Cground%2Cseason&limit=1000&order=date: {} method=GET, url=/parse/classes/Fixture?where=%7B%22season%22%3A%7B%22%24select%22%3A%7B%22key%22%3A%22objectId%22%2C%22query%22%3A%7B%22where%22%3A%7B%22fullIdentifier%22%3A%22CD117%22%7D%2C%22className%22%3A%22Season%22%7D%7D%7D%7D&include=home%2ChomeResult%2Chome.club%2Chome.ground%2Caway%2CawayResult%2Caway.club%2Cground%2Cseason&limit=1000&order=date, host=localhost:1337, accept=*/*, x-parse-application-id=[REDACTED], x-parse-client-version=php1.2.2, x-parse-rest-api-key=[REDACTED], 
verbose: RESPONSE from [GET] /parse/classes/Fixture?where=%7B%22season%22%3A%7B%22%24select%22%3A%7B%22key%22%3A%22objectId%22%2C%22query%22%3A%7B%22where%22%3A%7B%22fullIdentifier%22%3A%22CD117%22%7D%2C%22className%22%3A%22Season%22%7D%7D%7D%7D&include=home%2ChomeResult%2Chome.club%2Chome.ground%2Caway%2CawayResult%2Caway.club%2Cground%2Cseason&limit=1000&order=date: {
  "response": {
    "results": []
  }
} results=[]

Related

1014

3678 ?

enhancement stale

All 36 comments

@flovilmart - Do you know if the request JSON is still correct? Maybe the keys have changed?

We haven't changed the API.

Can you point me in a direction to investigate further- I stepped through the code, but there was nothing obvious.

What SDK are you using?

I'm using the PHP SDK for the main application.

I've checked the JS SDK - same thing occurs.

Is season a pointer?

It is yes.

More context:

var season = new Parse.Query("Season");
season.equalTo("fullIdentifier", "CD117");
season.find({
    useMasterKey: true,  
    success: function(Seasons){
        console.log(Seasons);
    },
    error: function(e){
        console.log(e);
    }
});

Returns an object: [ ParseObject { _objCount: 0, className: 'Season', id: 'USbmLVfKWW' } ]

var season = new Parse.Query("Season");
season.equalTo("fullIdentifier", "CD117");

var query = new Parse.Query("Fixture");
query.matchesKeyInQuery("season", "objectId", season)
query.find({
    useMasterKey: true,  
    success: function(Fixtures){
        console.log(Fixtures);
    },
    error: function(e){
        console.log(e);
    }
});

Returns an empty array.

var query = new Parse.Query("Fixture");
query.equalTo("season", new Parse.Object("Season", {id: "USbmLVfKWW"}))
query.find({
    useMasterKey: true,  
    success: function(Fixtures){
        console.log(Fixtures);
    },
    error: function(e){
        console.log(e);
    }
});

Correctly returns the data - so I assume, something has happened to matchesKeyInQuery whereby it can't search for pointers? It used to be able to on the hosted server.

Alright, I believe I know what's going on. I'll have a look

@flovilmart - Anything I can try to help with? I'm on a short timescale and getting pressure from a client. If you can point me in the direction, I maybe able to create a patch. Thanks - appreciate your efforts, keeping parse update.

Basically, I believe the issue is that when you use matchesKeyInQuery, it will try to match the objectId instead of the full pointer.

To get started, can you open a PR with the failing test?

I'll get on it -

Awesome! Once the test is written, it's gonna be pretty easy to find the underlying issue :)

@flovilmart - Test complete, where should I look next, my friend?

Probably in RestQuery.js but let me check a few things first about your usage of the API, probably something's amiss.

I may have written the test wrong, but switched the keys around just in case: query.matchesKeyInQuery("season", "objectId", season) same result -

Just checked the PHP code - it seems the keys are supposed to be the other way around so - I've updated the JS test. Sorry about that -

Curious: Looks like it passes using Postgres: https://travis-ci.org/parse-community/parse-server/builds/226664092

@flovilmart - I'm desperate for a solution as the season starts on Saturday and really need the system to work identically to last year.

So - I've been digging around https://github.com/parse-community/parse-server/blob/025e7a321886becfe48778c152b01dd0cb3fd492/src/Adapters/Storage/Mongo/MongoTransform.js#L535 - Am I warm?

I'll work on a fix, I have a pretty good idea of what's going on.

You would be a life saver -

Did you try to use matchesQuery("season", seasonQuery) because it does exactly what you expect it to do.

I would lead with that next time. ahaha 馃槥 - Good to know. What's the best course of action:

1) update all the SDKs to include a message when key=="objectId" (Use matchesQuery instead)
2) update all the SDKs to call matchesQuery instead if key=="objectId"
3) Fix the server to allow key=="objectId"
4) Change the server to internally use the same function as matchesQuery if key=="objectId"
5) Nothing / maybe update the docs.

None of those, this depends on your data structure, any of each could be valid. Not sure how it was working on Parse.com, if because the target field "season" is a pointer, the objectId's are transformed to a pointer matching.

This is not that the server doesn't allow key=='objectId', this is a valid query when you do:

query.matchesKeyInQuery("seasonObjectId", "objectId", seasonQuery);

Where you seasonObjectId column is effectively a string, which is the objectId of a season object.

I see - that makes sense - so there are cases when people just save the ID instead of using a pointer. - Well, now i'm educated. Maybe FB had a fallback in case it returned no results, try a string value match first, then pointer if that failed.

Like I said we could convert those to pointers if the target field is a pointer, did it work before?

It absolutely 100% worked before.

I'm looking for a fix now

TBH' I still would recommend you to change your code, as I can't guarantee when the fix will be released.

@flovilmart - Way ahead of you :) - Thanks so much for your direction, in more ways than one, without you parse would likely fall apart.

Thanks for the kind words, but many other contributors make it work, and without them, I would fall apart.

@awgeorge I changed the nature of the issue as it's not a blocker for the moment, but more a nice to have. Is that fine by you?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings