Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query relational data in Parse JavaScript

I am quite new to Parse.

I have a database set up using this code:

var Class = Parse.Object.extend("Class");
var Team = Parse.Object.extend("Team");
var Student = Parse.Object.extend("Student");

var newClass = new Class();
newClass.set("name", className);
newClass.set("code", classCode);
newClass.set("creator", currentUser);
var classACL = new Parse.ACL(currentUser);
classACL.setPublicReadAccess(true);
newClass.setACL(classACL);

newClass.save();

for (var i = 0; i < teamNames.length; i++) {
    var team = new Team();
    team.set("name", teamNames[i]);
    var teamACL = new Parse.ACL(currentUser);
    teamACL.setPublicReadAccess(true);
    team.setACL(teamACL);

    team.save();

    for (var j = 0; j < studentNames[i].length; j++) {
        if (studentNames[i][j]) {
            var student = new Student();
            student.set("name", studentNames[i][j]);

            student.set("parent", team);

            student.save();
        }
    }

    team.set("parent", newClass);

    team.save();
}

newClass.save(null, {
    success: function(newClass) {
        //success
    },
    error: function(newClass, error) {
        //fail
    }
});

Here Class, Team, and Student are modeled as one-to-many relationships.

Now when a student signs up for the class using his or her own user account, the corresponding Student's user column is set to the current user.

Then I want to list all the classes whose creator OR one of its student's user column (if exists) equals to currentUser.

How do I create such a query referencing multiple classes in Parse (or how can I optimize the database so that such a query can be made as efficient as possible -- without having to create two separate queries?)

Any help is appreciated.

Clarification:

I knew that I could do an or query as described in Parse docs (I should have stated this in the question), however, my question is about doing so on relational data (defined by a pointer type property to parent). Here I need user be a property of a Student instance, which belongs to Team, and then to Class, and I'd like to filter only Class objects that has either its creator property or one of its grandchildren's (an instance of Student) user property equal to the currentUser, effectively listing only the classes that you created or are registered as a student.

like image 212
Sunwoo Park Avatar asked Nov 01 '15 07:11

Sunwoo Park


2 Answers

Since the current database schema is having nested Pointers, there is no easy way to achieve this without adjusting it.


Database Schema

In Class class, add a Relation or Array field to contain references to Student/User objects. If you use User as object pointer, we wouldn't need to look up for Student at first.

Query

I assume that you have students as new Array field in Class class. students contains User objects.

  var user = Parse.User.current();
  var studentQuery = new Parse.Query(Class);
  var creatorQuery = new Parse.Query(Class);

  studentQuery.equalTo("students", user);
  creatorQuery.equalTo("creator", user);
  var query = Parse.Query.or(studentQuery, creatorQuery);
  query.find().then(function(objects){
      // Proceed with the results
  },function(error){
      // Handle error
  });
like image 169
Ralphilius Avatar answered Oct 18 '22 10:10

Ralphilius


Ok, what you want to do in an OR query with an internal subquery. One call to parse and you can filter the student properties using the subquery.

var studentQuery = new Parse.Query(Student);
studentQuery.equalTo("user", Parse.User.current());

var firstQuery = new Parse.Query(Class);
firstQuery.matchesQuery("student", studentQuery);

var secondQuery = new Parse.Query(Class);
secondQuery.equalTo("creator", Parse.User.current());

var mainQuery = Parse.Query.or(firstQuery, secondQuery);
mainQuery.find({
    success: function(results) {
        // results contains a list of Classes where the user is either the creator or the user property of the student (if available)
    },
    error: function(error) {
        // There was an error.
    }
});
like image 25
Alexander Li Avatar answered Oct 18 '22 11:10

Alexander Li