booster
booster copied to clipboard
Allow define projection fields in read model queries
Add the select
method to project which fields you want to get in your read model query:
@Command({
authorize: 'all',
})
export class GetProductsCount {
public constructor(readonly filters: Record<string, any>) {}
public static async handle(): Promise<unknown> {
const searcher = Booster.readModel(ProductReadModel)
.filter({
sku: { contains: 'toy' },
or: [
{
description: { contains: 'fancy' },
},
{
description: { contains: 'great' },
},
],
})
.select(['sku', 'description'])
.skipInstance(true)
const result = await searcher.search()
return { count: result.length }
}
}
The searcher result using skipInstance
will generate an array of objects with the sku
and description
fields of the ProductReadModel
read model. If you don't use skipInstance
the result will be an array of ProductReadModel
instances.
Note: Using skipInstance
will skip any Read Models migrations that need to be applied to the result. If you need to apply migrations to the result, don't use skipInstance
.
Apply Sweep Rules to your PR?
- [ ] Apply: All docstrings and comments should be up to date.
- [ ] Apply: Do not include large chunks of commented-out code.
- [ ] Apply: Ensure that error logs use traceback during exceptions.
- [ ] Apply: Remove debug logs and print statements from production code.
- [ ] Apply: All the business logic in the 'src' folder for each package should have the corresponding unit tests in the 'test' folder in the same package.
- [ ] Apply: Avoid 'any' types when possible.
- [ ] Apply: If there's a simpler way to express a type, it should be used.
/integration sha=f759db3f44bbb758e31468a56d2c31972865b216
:x: Oh no! Integration tests have failed
:white_check_mark: Integration tests have finished successfully!
/integration sha=ed4d1caa659a52b4745a5362cbe025848d193f75
:white_check_mark: Integration tests have finished successfully!
/integration sha=fec44b84904d33b0a6617c5163dfd1b452d2adc0
:white_check_mark: Integration tests have finished successfully!
/integration sha=42af24b560b48557ce1ddbbdb0a6978ed30a31c4
:x: Oh no! Integration tests have failed
:x: Oh no! Integration tests have failed
/integration sha=40074363cc3d30a03eedafc0d1a7cf060f831fb4
:x: Oh no! Integration tests have failed
/integration sha=09d7db60d6eb540e98936a40b94870b1d50b61ec
Important Update
Changes have been made so that select
can be applied not only in code but also when querying read models via GraphQL.
The getFields
method in the GraphQLGenerator
class will build the select
that is passed on to the searcher based on what fields came in the GraphQL query. It will also identify which fields are arrays of objects so that the selected properties are treated correctly when querying the database.
The buildProjections
method found in query-helper.ts
of the Azure provider will build the SQL query and handle object and array fields accordingly.
To be able to keep the structure of object properties and their sub-properties, when fetching those fields from the database, they're fetched in dot notation, e.g., root.property.subProperty
. The helper nestProperties
method is then applied to the results to convert it to nested properties, e.g., {root: {property: {subProperty: "some value"}}}
.
:x: Oh no! Integration tests have failed
/integration sha=afd9d2be3ee9124c77b9b696aac6a73927921454
:white_check_mark: Integration tests have finished successfully!
/integration sha=8726201
:white_check_mark: Integration tests have finished successfully!