Reputation: 21838
I am trying to grab every project by the members within them -- I've created a sample datastructure though the actual structure is much larger (as in it would be difficult to restructure the database).
Here is my query:
var ref = new Firebase(FBURL + '/chat/meta/project');
var email = '[email protected]';
ref
.orderByChild("email")
.equalTo(email)
.on("child_added", function(snapshot) {
console.log(snapshot.val());
}
);
It is important to note that if I remove the .equalTo(email)
that it returns all of the "projects", when it should only return 2 of them.
Here is the data in Firebase:
{
"chat" : {
"meta" : {
"project" : {
"-KAgjWOxjk80HIbNr68M" : {
"name" : "Gman Branding",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:33:25.170Z",
"member" : {
"-KAgkD-2GVESwNwKP3fA" : {
"email" : "[email protected]"
},
"-KAgkP3M4nug9Bjn-vY6" : {
"email" : "[email protected]"
},
"-KAgkP3OF0sUgc9x9p37" : {
"email" : "[email protected]"
},
"-KAgkaMyEOiXft6o-HbO" : {
"email" : "[email protected]"
}
}
},
"-KAgl9xlPDU5T4072FgE" : {
"-KAglqH9pxkhgC84_kAl" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "billing test 1",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-02-25T23:18:55.626Z",
"dateNotifyUnread" : "2016-01-25T23:23:55.626Z",
"member" : {
"-KAglNsswyk66qUZNrTU" : {
"email" : "[email protected]"
}
}
},
"-KAgltmLk2oOYhEDfwRL" : {
"-KAgm1Jt5q53gzLm1GIh" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm1Jvss9AMZa1qDb7" : {
"email" : "[email protected]"
}
}
},
"-KAgluTcE_2dv00XDm1L" : {
"-KAgm6ENmkpDiDG2lqZ4" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"-KAgmBptbeInutRzNinm" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm6EQcvQg3oP-OnIF" : {
"email" : "[email protected]"
},
"-KAgmBpwoxPYGXS9fLZ9" : {
"email" : "[email protected]"
}
}
}
}
}
}
}
I've looked at 8-10 other links on SO but haven't found any that solve this issue.
Upvotes: 2
Views: 2550
Reputation: 598740
The solution is to create a data structure that matches your needs. In this case, you want to look up the projects for a user based on their email address. So we'll add a node that contains this mapping:
"projects_by_email": {
"kerry@email,com": {
"-KAgjWOxjk80HIbNr68M": true,
"-KAgl9xlPDU5T4072FgE": true
},
"abc@gman,com": {
"-KAgjWOxjk80HIbNr68M": true
}
...
}
This is called denormalizing your data, although I often think of them as inverted indexes. I would probably keep the projects by uid, but the structure would be the same.
With a structure like this, you can get the list of projects for an email with a simple direct look up:
var ref = new Firebase(FBURL);
var email = '[email protected]';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
console.log(snapshot.key());
}
);
Or if you then also want to "join" the projects themselves:
var ref = new Firebase(FBURL);
var email = '[email protected]';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
ref.child('project').child(snapshot.key()).once('value', function(projectSnapshot) {
console.log(projectSnapshot.val());
});
}
);
This type of denormalizing is a normal part of NoSQL data modeling. The duplication may feel wasteful, but it is part of why NoSQL solution scale so well: none of the code above asks the database to consider all projects/all users. It's all directly accessing the correct nodes, which scales really well. So we're sacrificing storage space to gain improved performance/scalability; a typical space vs time trade-off.
Upvotes: 3