When querying a document that contains a subcollection, the subcollection is not automatically queried and must be queried manually. This enhancement proposes adding support for eager loading of subcollections to simplify querying nested data structures.
Steps to Reproduce
Query a document that contains a subcollection.
Observe that the subcollection is not automatically loaded and must be queried manually.
Expected Behavior
Subcollections should be automatically queried and loaded when querying the parent document, based on specified eager loading properties.
Actual Behavior
Subcollections are not automatically queried and must be manually loaded after querying the parent document.
Acceptance Criteria
Implement a mechanism to support eager loading of subcollections.
Ensure that the eager loading properties can be specified when querying the parent document.
Add unit tests to validate the functionality of eager loading subcollections.
Additional Context
April 15, 2022: Initial issue raised about querying subcollections.
June 17, 2022: Discussion about the limitations and openness to suggestions.
December 13, 2022: Suggestion to implement eager loading properties when querying data.
Proposed API Changes
Add Eager Loading Support:
Introduce an eagerLoad method to specify subcollections that should be eagerly loaded when querying the parent document.
// Example of adding eager loading support to the query builder
class QueryBuilder<T> {
private eagerLoadProps: Array<IWherePropParam<T>> = [];
eagerLoad(...props: Array<IWherePropParam<T>>): this {
for (const prop of props) {
if (isSubCollection(prop)) {
this.eagerLoadProps.push(prop);
}
}
return this;
}
// Other existing methods...
}
Modify Repository Execution:
Update the repository execution method to handle eager loading of subcollections.
// Example of modifying the repository execution method
class BaseFirestoreRepository<T> {
async execute(
queries: Array<IFireOrmQueryLine>,
limitVal?: number,
orderByObj?: IOrderByParams,
single?: boolean,
customQuery?: ICustomQuery<T>,
eagerLoadedProps?: Array<IWherePropParam<T>>
): Promise<T[]> {
let query = queries.reduce<Query>((acc, cur) => {
const op = cur.operator as WhereFilterOp;
return acc.where(cur.prop, op, cur.val);
}, this.firestoreColRef);
const executedQuery = query.get().then(this.extractTFromColSnap);
if (eagerLoadedProps && eagerLoadedProps.length > 0) {
const results = await executedQuery;
await Promise.all(
results.map(async result => {
for (const prop of eagerLoadedProps) {
const subCollection = result[prop as keyof T] as ISubCollection<any>;
result[prop as keyof T] = await subCollection.get();
}
})
);
return results;
}
return executedQuery;
}
// Other existing methods...
}
Unit Tests:
Add unit tests to validate the eager loading functionality for subcollections.
// Example unit test for eager loading subcollections
test('should eagerly load subcollections', async () => {
const bandRepository = getRepository(Band);
const band = await bandRepository
.whereGreaterThan(band => band.formationYear, 1985)
.whereArrayContains(band => band.genres, 'progressive-rock')
.eagerLoad(band => band.albums)
.find();
expect(band.albums).toBeDefined();
expect(band.albums.length).toBeGreaterThan(0);
});
Example Implementation
class Album {
id: string;
name: string;
year: number;
}
@Collection()
class Band {
id: string;
name: string;
formationYear: number;
genres: Array<string>;
@SubCollection(Album, 'albums')
albums?: ISubCollection<Album>;
}
const bandRepository = getRepository(Band);
const band = await bandRepository
.whereGreaterThan(band => band.formationYear, 1985)
.whereArrayContains(band => band.genres, 'progressive-rock')
.eagerLoad(band => band.albums)
.find();
console.log(band.albums.map(album => album.name)); // Correctly prints the albums' names
Description
When querying a document that contains a subcollection, the subcollection is not automatically queried and must be queried manually. This enhancement proposes adding support for eager loading of subcollections to simplify querying nested data structures.
Steps to Reproduce
Expected Behavior
Subcollections should be automatically queried and loaded when querying the parent document, based on specified eager loading properties.
Actual Behavior
Subcollections are not automatically queried and must be manually loaded after querying the parent document.
Acceptance Criteria
Additional Context
Proposed API Changes
Add Eager Loading Support:
eagerLoad
method to specify subcollections that should be eagerly loaded when querying the parent document.Modify Repository Execution:
Unit Tests:
Example Implementation
Original Issue