Home > Net >  Searching within collection collectionGroup query
Searching within collection collectionGroup query

Time:03-10

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.

  • Related