Firestore query subcollections
Firestore query subcollections
I thought I read that you can query subcollections with the new Firebase Firestore, but I don't see any examples. For example I have my Firestore setup in the following way:
How would I be able to query "Find all dances where songName == 'X'"
6 Answers
6
This is a feature which does not yet exist. It's called a "collection group query" and would allow you query all songs regardless of which dance contained them. This is something we intend to support but don't have a concrete timeline on when it's coming.
The alternative structure at this point is to make songs a top-level collection and make which dance the song is a part of a property of the song.
We agree! There's just a limited number of hours in the day :-).
– Gil Gilbert
Nov 4 '17 at 20:54
I don't understand, for what do people pay, if the firebase is limited? Seems like even Backendless has more functionality than Firebase. And why is Firebase so popular? Seems people got crazy
– nzackoya
Nov 10 '17 at 21:56
This feature is highly needed or else people will start finding alternatives, even we have deadlines to meet. :P
– JD-V
Nov 30 '17 at 13:11
We need this feature . At lease the timeline to release this will help us to be prepared.
– sanjaya panigrahy
Feb 8 at 11:40
What if you store songs as an object instead of as a collection? Each dance as, with songs as a field: type Object (not a collection)
{
danceName: "My Dance",
songs: {
"aNameOfASong": true,
"aNameOfAnotherSong": true,
}
}
then you could query for all dances with aNameOfASong:
db.collection('Dances')
.where('songs.aNameOfASong', '==', true)
.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
This solution would work but it is not scalable in case the number of songs is large or can grow dynamically. This would increase the document size and affect the read/write performance. More about this can be found in Firebase documentation linked below (see the last section 'Limitations' on the page) firebase.google.com/docs/firestore/solutions/arrays
– Nouman Hanif
Feb 13 at 21:49
@Nelson.b.austin Since firestore does not have that yet, I suggest you to have a flat structure, meaning:
Dances = {
danceName: 'Dance name 1',
songName_Title1: true,
songName_Title2: true,
songName_Title3: false
}
Having it in that way, you can get it done:
var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);
I hope this helps.
what is
songName_Title3: false
useful for? if I am not wrong, it can only be used to search for dances that don't have a specific song name assuming that us need a songName_Title3: false
to make dances.where("songName_"+songTitle, "==", false);
return such results it would not make sence for every dance to have boolean flags for every possible song name...– epeleg
Mar 26 at 19:54
songName_Title3: false
songName_Title3: false
dances.where("songName_"+songTitle, "==", false);
It could be better to use a flat data structure.
The docs specify the pros and cons of different data structures on this page.
Specifically about the limitations of structures with sub-collections:
You can't easily delete subcollections, or perform compound queries across subcollections.
Contrasted with the purported advantages of a flat data structure:
Root-level collections offer the most flexibility and scalability, along with powerful querying within each collection.
You can always search like this:-
this.key$ = new BehaviorSubject(null);
return this.key$.switchMap(key =>
this.angFirestore
.collection("dances").doc("danceName").collections("songs", ref =>
ref
.where("songName", "==", X)
)
.snapshotChanges()
.map(actions => {
if (actions.toString()) {
return actions.map(a => {
const data = a.payload.doc.data() as Dance;
const id = a.payload.doc.id;
return { id, ...data };
});
} else {
return false;
}
})
);
As stated by Gil Gilbert, it seems as if collection group queries is currently in the works. In the mean time it is probably better to use root level collections and just link between these collection using the document UID's.
For those who don't already know, Jeff Delaney has some incredible guides and resources for anyone working with Firebase (and Angular) on AngularFirebase.
Firestore NoSQL Relational Data Modeling - Here he breaks down the basics of NoSQL and Firestore DB structuring
Advanced Data Modeling With Firestore by Example - These are more advanced techniques to keep in the back of your mind. A great read for those wanting to take there Firestore skills to the next level
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It would be MUCH better if the Firestore dev team implemented subcollection queries ASAP. After all, 'more powerful queries' is one of the major selling points according to the Firestore manual. Right now, Firestore is like a Porsche without wheels.
– Arne Wolframm
Nov 4 '17 at 0:38