payload
payload copied to clipboard
perf(db-mongodb): use aggregations for relationship querying
Uses lookups for relationships querying (where { relationship.name }
) of subquerying.
Before, whenever we needed to query by a property from another document, we did this:
const result = await SubModel.find(subQuery, subQueryOptions)
const $in: unknown[] = []
result.forEach((doc) => {
const stringID = doc._id.toString()
$in.push(stringID)
if (mongoose.Types.ObjectId.isValid(stringID)) {
$in.push(doc._id)
}
})
Now, we are building an aggregation with lookups to query by those!
Benchmark
Benchmark in test/relationships/int.ts
- before https://github.com/r1tsuu/payload/tree/bench/aggregations-before after https://github.com/r1tsuu/payload/tree/bench/aggregations-after
Run with:
pnpm exec cross-env NODE_OPTIONS="--no-deprecation" node 'node_modules/jest/bin/jest.js' '/Users/ritsu/work/payload-3/test/relationships/int.spec.ts' -c '/Users/ritsu/work/payload-3/test/jest.config.js' -t 'Relationships Querying Nested Querying should allow querying several times, one and two level deep'
Code that benchmark uses: https://github.com/r1tsuu/payload/blob/1b8eb31fa56a45316d520e92ddcb2f5c3800a0dd/test/relationships/int.spec.ts#L878-L926
Results:
Before:
After:
Additionally
- Ensures we always use the transaction when building the query. We didn't do this before for relationship querying.
- Unblocks sorting by relationships in mongodb (we support it with postgres/sqlite adapters), can implement in a separate PR.