###### Data Modeling and Structuring

Discover advanced strategies and practical hacks to optimize Firestore index usage, reduce index consumption, and overcome query limitations. Effectively manage strings, arrays, and large datasets to improve your application’s performance and scalability.

Mar 17, 2025

[#firestore](/content/blog/tag/firestore/index.html) [#indexing](/content/blog/tag/indexing/index.html) [#performance](/content/blog/tag/performance/index.html) [#optimization](/content/blog/tag/optimization/index.html) [#queries](/content/blog/tag/queries/index.html)

# Optimizing Index Usage in Firestore: Effective Strategies and Hacks

Firestore is an exceptional NoSQL database offered by Firebase, but it comes with limitations, particularly regarding indexing. Optimizing indexes is critical, especially when approaching Firestore’s default limit of 200 composite indexes per database. Here are strategies and effective “hacks” to enhance query efficiency and reduce index usage:

#### Understanding Firestore Indexing Limitations

Firestore supports single-field and composite indexes. While single-field indexes are automatic, composite indexes, essential for complex queries, must be defined manually. Each composite index typically consumes part of the 200-index limit, which requires thoughtful management.

#### Best Practices to Optimize Firestore Indexes

1. **Store Strings Efficiently**  
   - Always store strings in lowercase to simplify search queries.  
   - Use external tools like Algolia for advanced search capabilities, relieving Firestore from extensive indexing.
2. **Managing Arrays of Strings**  
   Firestore allows querying arrays using `array-contains` and `array-contains-any`, but these methods have limitations:
   - `array-contains` supports only one value per query.  
   - `array-contains-any` returns documents matching any of the given values, which isn’t useful when all selected filters must match.

**Efficient Solution:** Store arrays with precomputed combinations.

Example:

```javascript
services: ["wifi", "pool"];
searchableServices: ["pool,wifi", "pool", "wifi"];
```

To query documents having both ‘wifi’ and ‘pool’:

```javascript
.where('searchableServices', 'array-contains-any', ['pool,wifi', 'wifi'])
```

Always generate combinations consistently (alphabetically sorted).

#### Reducing Index Usage: Useful Hacks

1. **Sorting and Index Reduction**  
Embed sorting fields in arrays to potentially avoid additional indexes.

Example:

```javascript
searchableServices: [
     5, // rating or priority
     "wifi,pool",
     "wifi",
];
```

Now sorting by rating becomes straightforward:

```javascript
.orderBy('searchableServices', 'desc')
```

2. **Search Queries Without Additional Indexes**  
Avoid range queries (`>=`, `<=`) by using precomputed substrings:

Example for a searchable name:

```javascript
searchableNames: ["santi", "sant", "san", "sa", "s"];
```

Query:

```javascript
.where('searchableNames', 'array-contains', 'san')
```

This approach efficiently retrieves entries without requiring extra indexes for range queries.

#### Handling Large Number of Options (e.g., Services)

With extensive service options, storing every possible combination isn’t feasible. Instead:

- Store services simply:

```javascript
services: { wifi: true, pool: true }
```

- Generate searchable combinations dynamically using Cloud Functions or callbacks.  
- Ensure logic prevents infinite loops, checking modifications carefully before applying updates.

#### Key Considerations

- **Consistency:** Always generate searchable arrays consistently (e.g., alphabetical order).  
- **Testing:** Regularly test query performance and indexing requirements using Firestore’s built-in emulator and tools.

### Conclusion

Optimizing indexes in Firestore involves strategic data structuring and clever hacks to avoid extensive indexing requirements. By carefully managing how data is stored and queried, you can significantly enhance application performance and stay comfortably within Firestore’s indexing limitations.
