Skip to content

Commit

Permalink
perf(db-mongodb): use aggregations for relationship querying
Browse files Browse the repository at this point in the history
  • Loading branch information
r1tsuu committed Oct 24, 2024
1 parent 0fcbce3 commit f2ba72c
Show file tree
Hide file tree
Showing 23 changed files with 409 additions and 225 deletions.
22 changes: 19 additions & 3 deletions packages/db-mongodb/src/count.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { QueryOptions } from 'mongoose'
import type { AggregateOptions, PipelineStage, QueryOptions } from 'mongoose'
import type { Count, PayloadRequest } from 'payload'

import { flattenWhereToOperators } from 'payload'
Expand All @@ -12,7 +12,7 @@ export const count: Count = async function count(
{ collection, locale, req = {} as PayloadRequest, where },
) {
const Model = this.collections[collection]
const options: QueryOptions = await withSession(this, req)
const options: AggregateOptions & QueryOptions = await withSession(this, req)

let hasNearConstraint = false

Expand All @@ -21,9 +21,12 @@ export const count: Count = async function count(
hasNearConstraint = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'))
}

const query = await Model.buildQuery({
const pipeline: PipelineStage[] = []

const query = Model.buildQuery({
locale,
payload: this.payload,
pipeline,
where,
})

Expand All @@ -40,6 +43,19 @@ export const count: Count = async function count(
}
}

if (pipeline.length) {
pipeline.push({ $match: query })
pipeline.push({
$count: 'count',
})

const result = await Model.aggregate(pipeline, options)

return {
totalDocs: result.length > 0 ? result[0].count : 0,
}
}

const result = await Model.countDocuments(query, options)

return {
Expand Down
8 changes: 6 additions & 2 deletions packages/db-mongodb/src/deleteMany.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import type { QueryOptions } from 'mongoose'
import type { DeleteMany, PayloadRequest } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildQueryWithAggregate } from './utilities/buildQueryWithAggregate.js'
import { withSession } from './withSession.js'

export const deleteMany: DeleteMany = async function deleteMany(
this: MongooseAdapter,
{ collection, req = {} as PayloadRequest, where },
) {
const Model = this.collections[collection]
const options = {
const options: QueryOptions = {
...(await withSession(this, req)),
lean: true,
}

const query = await Model.buildQuery({
const query = await buildQueryWithAggregate({
Model,
payload: this.payload,
session: options.session,
where,
})

Expand Down
5 changes: 4 additions & 1 deletion packages/db-mongodb/src/deleteOne.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { DeleteOne, Document, PayloadRequest } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildQueryWithAggregate } from './utilities/buildQueryWithAggregate.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'

Expand All @@ -12,8 +13,10 @@ export const deleteOne: DeleteOne = async function deleteOne(
const Model = this.collections[collection]
const options = await withSession(this, req)

const query = await Model.buildQuery({
const query = await buildQueryWithAggregate({
Model,
payload: this.payload,
session: options.session,
where,
})

Expand Down
8 changes: 6 additions & 2 deletions packages/db-mongodb/src/deleteVersions.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import type { QueryOptions } from 'mongoose'
import type { DeleteVersions, PayloadRequest } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildQueryWithAggregate } from './utilities/buildQueryWithAggregate.js'
import { withSession } from './withSession.js'

export const deleteVersions: DeleteVersions = async function deleteVersions(
this: MongooseAdapter,
{ collection, locale, req = {} as PayloadRequest, where },
) {
const VersionsModel = this.versions[collection]
const options = {
const options: QueryOptions = {
...(await withSession(this, req)),
lean: true,
}

const query = await VersionsModel.buildQuery({
const query = await buildQueryWithAggregate({
locale,
Model: VersionsModel,
payload: this.payload,
session: options.session,
where,
})

Expand Down
16 changes: 11 additions & 5 deletions packages/db-mongodb/src/find.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { PaginateOptions } from 'mongoose'
import type { PaginateOptions, PipelineStage } from 'mongoose'
import type { Find, PayloadRequest } from 'payload'

import { flattenWhereToOperators } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildSortParam } from './queries/buildSortParam.js'
import { buildJoinAggregation } from './utilities/buildJoinAggregation.js'
import { buildAggregation } from './utilities/buildJoinAggregation.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'

Expand All @@ -19,7 +19,6 @@ export const find: Find = async function find(
locale,
page,
pagination,
projection,
req = {} as PayloadRequest,
sort: sortArg,
where,
Expand Down Expand Up @@ -47,9 +46,14 @@ export const find: Find = async function find(
})
}

const query = await Model.buildQuery({
const pipeline: PipelineStage[] = []
const projection: Record<string, boolean> = {}

const query = Model.buildQuery({
locale,
payload: this.payload,
pipeline,
projection,
where,
})

Expand Down Expand Up @@ -103,13 +107,15 @@ export const find: Find = async function find(

let result

const aggregate = await buildJoinAggregation({
const aggregate = buildAggregation({
adapter: this,
collection,
collectionConfig,
joins,
limit,
locale,
pipeline,
projection,
query,
})
// build join aggregation
Expand Down
8 changes: 6 additions & 2 deletions packages/db-mongodb/src/findGlobal.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { QueryOptions } from 'mongoose'
import type { FindGlobal, PayloadRequest } from 'payload'

import { combineQueries } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildQueryWithAggregate } from './utilities/buildQueryWithAggregate.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'

Expand All @@ -12,15 +14,17 @@ export const findGlobal: FindGlobal = async function findGlobal(
{ slug, locale, req = {} as PayloadRequest, where },
) {
const Model = this.globals
const options = {
const options: QueryOptions = {
...(await withSession(this, req)),
lean: true,
}

const query = await Model.buildQuery({
const query = await buildQueryWithAggregate({
globalSlug: slug,
locale,
Model,
payload: this.payload,
session: options.session,
where: combineQueries({ globalType: { equals: slug } }, where),
})

Expand Down
28 changes: 25 additions & 3 deletions packages/db-mongodb/src/findGlobalVersions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PaginateOptions } from 'mongoose'
import type { AggregatePaginateResult, PaginateOptions, PipelineStage } from 'mongoose'
import type { FindGlobalVersions, PayloadRequest } from 'payload'

import { buildVersionGlobalFields, flattenWhereToOperators } from 'payload'
Expand Down Expand Up @@ -52,10 +52,15 @@ export const findGlobalVersions: FindGlobalVersions = async function findGlobalV
})
}

const query = await Model.buildQuery({
const pipeline: PipelineStage[] = []
const projection: Record<string, boolean> = {}

const query = Model.buildQuery({
globalSlug: global,
locale,
payload: this.payload,
pipeline,
projection,
where,
})

Expand Down Expand Up @@ -107,7 +112,24 @@ export const findGlobalVersions: FindGlobalVersions = async function findGlobalV
}
}

const result = await Model.paginate(query, paginationOptions)
let result: AggregatePaginateResult<unknown>

if (pipeline.length) {
pipeline.push({ $sort: { createdAt: -1 } })

if (limit) {
pipeline.push({ $limit: limit })
}

if (Object.keys(projection).length > 0) {
pipeline.push({ $project: projection })
}

result = await Model.aggregatePaginate(Model.aggregate(pipeline), paginationOptions)
} else {
result = await Model.paginate(query, paginationOptions)
}

const docs = JSON.parse(JSON.stringify(result.docs))

return {
Expand Down
15 changes: 11 additions & 4 deletions packages/db-mongodb/src/findOne.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { MongooseQueryOptions } from 'mongoose'
import type { MongooseQueryOptions, PipelineStage } from 'mongoose'
import type { Document, FindOne, PayloadRequest } from 'payload'

import type { MongooseAdapter } from './index.js'

import { buildJoinAggregation } from './utilities/buildJoinAggregation.js'
import { buildAggregation } from './utilities/buildJoinAggregation.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'

Expand All @@ -18,19 +18,26 @@ export const findOne: FindOne = async function findOne(
lean: true,
}

const query = await Model.buildQuery({
const pipeline: PipelineStage.Lookup[] = []
const projection: Record<string, boolean> = {}

const query = Model.buildQuery({
locale,
payload: this.payload,
pipeline,
projection,
where,
})

const aggregate = await buildJoinAggregation({
const aggregate = buildAggregation({
adapter: this,
collection,
collectionConfig,
joins,
limit: 1,
locale,
pipeline,
projection,
query,
})

Expand Down
28 changes: 25 additions & 3 deletions packages/db-mongodb/src/findVersions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PaginateOptions } from 'mongoose'
import type { AggregatePaginateResult, PaginateOptions, PipelineStage } from 'mongoose'
import type { FindVersions, PayloadRequest } from 'payload'

import { flattenWhereToOperators } from 'payload'
Expand Down Expand Up @@ -49,9 +49,14 @@ export const findVersions: FindVersions = async function findVersions(
})
}

const query = await Model.buildQuery({
const pipeline: PipelineStage[] = []
const projection: Record<string, boolean> = {}

const query = Model.buildQuery({
locale,
payload: this.payload,
pipeline,
projection,
where,
})

Expand Down Expand Up @@ -103,7 +108,24 @@ export const findVersions: FindVersions = async function findVersions(
}
}

const result = await Model.paginate(query, paginationOptions)
let result: AggregatePaginateResult<unknown>

if (pipeline.length) {
pipeline.push({ $sort: { createdAt: -1 } })

if (limit) {
pipeline.push({ $limit: limit })
}

if (Object.keys(projection).length > 0) {
pipeline.push({ $project: projection })
}

result = await Model.aggregatePaginate(Model.aggregate(pipeline), paginationOptions)
} else {
result = await Model.paginate(query, paginationOptions)
}

const docs = JSON.parse(JSON.stringify(result.docs))

return {
Expand Down
4 changes: 1 addition & 3 deletions packages/db-mongodb/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export const init: Init = function init(this: MongooseAdapter) {
}),
)

if (Object.keys(collection.joins).length > 0) {
versionSchema.plugin(mongooseAggregatePaginate)
}
versionSchema.plugin(mongooseAggregatePaginate)

const model = mongoose.model(
versionModelName,
Expand Down
4 changes: 1 addition & 3 deletions packages/db-mongodb/src/models/buildCollectionSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ export const buildCollectionSchema = (
.plugin<any, PaginateOptions>(paginate, { useEstimatedCount: true })
.plugin(getBuildQueryPlugin({ collectionSlug: collection.slug }))

if (Object.keys(collection.joins).length > 0) {
schema.plugin(mongooseAggregatePaginate)
}
schema.plugin(mongooseAggregatePaginate)

return schema
}
Loading

0 comments on commit f2ba72c

Please sign in to comment.