Alex Mitchell
Alex Mitchell

Reputation: 400

Querying by nested pointers?

I'm rewriting a "Yelp for Dorm rooms" web app in Node/Express with a Parse backend (PHP version here for context).

Since I am very used to SQL databases, I have organized my data into four tables of one-to-many pointers:

Rooms
Halls
Clusters
Campuses

Every room has a pointer to its hall, each hall has a pointer to its cluster (a small group of halls) and each cluster has a pointer to its campus.

However, since each hall/cluster/campus has its own culture, I want to be able to search by each level (e.g. I want to live on South campus, or Norris Hall). However, since the pointers are nested three levels deep, I'm having a problem searching by campus and returning rooms. I'd hate to have to duplicate data and copy/paste cluster and campus data into each room object.

Searching for a cluster is easy. I can just:

var clusterQuery = new Parse.Query("clusters");
clusterQuery.equalTo("cluster", req.params.cluster);
var hallsQuery = new Parse.Query("halls");
hallsQuery.matchesQuery("cluster", clusterQuery);
query.matchesQuery("hall", hallsQuery);

So I figured doing a campus search would be simply

var campusQuery = new Parse.Query("campuses");
campusQuery.equalTo("cluster", req.params.campus);
var clusterQuery = new Parse.Query("clusters");
clusterQuery.matchesQuery("campus", campusQuery);
var hallsQuery = new Parse.Query("halls");
hallsQuery.matchesQuery("cluster", clusterQuery);
query.matchesQuery("hall", hallsQuery);

But of course, that would be too easy.

Instead, I get an error 154: Query had too many nested queries.

So my question for you, almighty Stackoverflow community: What should I do instead?

Upvotes: 0

Views: 790

Answers (1)

knshn
knshn

Reputation: 3461

It makes more sense to name your classes with singular names, Campus rather than Campuses. So, I will go with singular names.

Your model is a tree structure and there are some patterns for it. The one you use is keeping parent references, that is simple but requires multiple queries for subtrees as you realized. Since Parse is using MongoDB, you can check use cases and model patterns of MongoDB, such as Product Catalog and Model Tree Structures.

Consider Array of Ancestors pattern where you have something like {_id: "Room1", ancestors: [pointerToAHall, pointerToACluster, pointerToACampus], parrent: pointerToAHall}.

You can find rooms where ancestors array contains a campus:

var query = new Parse.Query("Room");
query.equalTo("ancestors", aCampusObject)

Note that equalTo knows that ancestors is an array. You may want to check Parse docs for queries on array.

Upvotes: 2

Related Questions