Shawn
Shawn

Reputation: 163

Firestore: Accessing more composite custom indexes with a simpler query

On Firebase Firestore, if the client tries to access more composite custom index with a simpler query, would it work?

For example, let's say there's a collection and I set a custom composite index of its fields like this: field1 Ascending / field2 Ascending / field3 Descending

On the client, trying to get a document .where("field1", isEqualTo: smth).where("field2", isEqualTo: smth).where("field3", isEqualTo: smth) would work, but what if there's one less .where() like this: .where("field1", isEqualTo: smth).where("field2", isEqualTo: smth)

Would the second query (which doesn't query field3) still work even if the more composite index (which indexes 3 fields) is set? Or would I have to add a new custom index that only indexes those two fields?

Upvotes: 0

Views: 192

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138989

Cloud Firestore needs an index for every query you perform. However, there are situations in which it doesn't necessarily require one. If you're querying Firestore using multiple equality clauses and an orderBy, then it can re-use existing indexes. So it can merge the indexes for simple equality filters to build the composite indexes needed for larger equality queries.

So let's take your example. If you perform the following query without ordering:

db.collection("someCollection").where("field1", isEqualTo: smth)
                               .where("field2", isEqualTo: smth)
                               .where("field3", isEqualTo: smth)

There is no need for an index at all, as it is created automatically. If you, however, add an orderBy:

db.collection("someCollection").where("field1", isEqualTo: smth)
                               .where("field2", isEqualTo: smth)
                               .where("field3", isEqualTo: smth)
                               .orderBy("someField")

Then indeed an index is required. That's the most common case in which Firestore can reuse indexes. So if for example, you create the following indexes:

Collection Fields indexed Query scope
someCollection ↑ field1 ↑ someField Collection
someCollection ↑ field2 ↑ someField Collection
someCollection ↑ field3 ↑ someField Collection

This means that the above query will work perfectly fine, but the below queries will also work:

db.collection("someCollection").where("field1", isEqualTo: smth)
                               .orderBy("someField")

And:

db.collection("someCollection").where("field1", isEqualTo: smth)
                               .where("field2", isEqualTo: smth)
                               .orderBy("someField")

See the absence of .where("field3", isEqualTo: smth)? The same rules apply if you need a descending order.

Upvotes: 1

Related Questions