So I came across this answer which allows limiting the collectionGroup query to a specific document: CollectionGroupQuery but limit search to subcollections under a particular document
However I also want to further filter results based on a specific field using where
, which required an index. The query works without errors but it always returns empty snapshot:
const cityRef = firebase.firestore().doc('cities/cityId');
firebase.firestore().collectionGroup('attractions')
.where('name', '>=', keywords),
.where('name', '<=', keywords '\uf8ff')
.orderBy('name')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(cityRef.path),
.endAt(cityRef.path "\uf8ff")
.get()
.then((querySnapshot) => {
console.log("Found " querySnapshot.size " docs");
querySnapshot.forEach((doc) => console.log("> " doc.ref.path))
})
.catch((err) => {
console.error("Failed to execute query", err);
})
CodePudding user response:
firebaser here
The problem is almost certainly that your query has range checks on two different fields (name
and the document path), which isn't possible in Firestore's query model. As the documentation on query limitations says:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.
Your startAt
and endAt
clauses are just different ways of writing >
and <
as far as this limitation is concerned.
I'm not sure why the SDK isn't throwing an error for that here though, and am inclined to think that's a bug in the SDK.
Update: after chatting with one of our SDK engineers, it seems the use-case should be possible, but you'll need to pass all relevant fields to startAt
and endAt
so that it can determine the correct slice across all those field values.
Doing that would also remove the need to even have the where
, so it'd be:
firebase.firestore().collectionGroup('attractions')
.orderBy('name')
.orderBy(firebase.firestore.FieldPath.documentId())
.startAt(keywords, cityRef.path),
.endAt(keywords '\uf8ff', cityRef.path "\uf8ff")
.get()
...
I've been trying to get that working in this jsbin (https://jsbin.com/yiyifin/edit?js,console), so far without success, but I'll post back if I get it working or have a final verdict on why it doesn't work.