Migrates the `db-mongodb` package to use `strict: true` and `noUncheckedIndexedAccess: true` TSConfig properties. This greatly improves code quality and prevents some runtime errors or gives better error messages.
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import type { CountOptions } from 'mongodb'
|
|
import type { Count } from 'payload'
|
|
|
|
import { flattenWhereToOperators } from 'payload'
|
|
|
|
import type { MongooseAdapter } from './index.js'
|
|
|
|
import { buildQuery } from './queries/buildQuery.js'
|
|
import { getCollection } from './utilities/getEntity.js'
|
|
import { getSession } from './utilities/getSession.js'
|
|
|
|
export const count: Count = async function count(
|
|
this: MongooseAdapter,
|
|
{ collection: collectionSlug, locale, req, where = {} },
|
|
) {
|
|
const { collectionConfig, Model } = getCollection({ adapter: this, collectionSlug })
|
|
|
|
const options: CountOptions = {
|
|
session: await getSession(this, req),
|
|
}
|
|
|
|
let hasNearConstraint = false
|
|
|
|
if (where) {
|
|
const constraints = flattenWhereToOperators(where)
|
|
hasNearConstraint = constraints.some((prop) => Object.keys(prop).some((key) => key === 'near'))
|
|
}
|
|
|
|
const query = await buildQuery({
|
|
adapter: this,
|
|
collectionSlug,
|
|
fields: collectionConfig.flattenedFields,
|
|
locale,
|
|
where,
|
|
})
|
|
|
|
// useEstimatedCount is faster, but not accurate, as it ignores any filters. It is thus set to true if there are no filters.
|
|
const useEstimatedCount = hasNearConstraint || !query || Object.keys(query).length === 0
|
|
|
|
if (!useEstimatedCount && Object.keys(query).length === 0 && this.disableIndexHints !== true) {
|
|
// Improve the performance of the countDocuments query which is used if useEstimatedCount is set to false by adding
|
|
// a hint. By default, if no hint is provided, MongoDB does not use an indexed field to count the returned documents,
|
|
// which makes queries very slow. This only happens when no query (filter) is provided. If one is provided, it uses
|
|
// the correct indexed field
|
|
options.hint = {
|
|
_id: 1,
|
|
}
|
|
}
|
|
|
|
let result: number
|
|
if (useEstimatedCount) {
|
|
result = await Model.estimatedDocumentCount({ session: options.session })
|
|
} else {
|
|
result = await Model.countDocuments(query, options)
|
|
}
|
|
|
|
return {
|
|
totalDocs: result,
|
|
}
|
|
}
|