diff --git a/src/collection/collection.ts b/src/collection/collection.ts index b9382632..13943b1e 100644 --- a/src/collection/collection.ts +++ b/src/collection/collection.ts @@ -73,6 +73,9 @@ export class Collection { return result.value; } + /** + * @deprecated Use `countDocuments` or `estimatedDocumentCount` instead + */ async count(filter?: Document, options?: CountOptions): Promise { const res = await this.#protocol.commandSingle(this.#dbName, { count: this.name, @@ -87,6 +90,43 @@ export class Collection { } } + async countDocuments( + filter?: Document, + options?: CountOptions, + ): Promise { + const pipeline: Document[] = [{ $match: filter }]; + + if (typeof options?.skip === "number") { + pipeline.push({ $skip: options.skip }); + delete options.skip; + } + + if (typeof options?.limit === "number") { + pipeline.push({ $limit: options.limit }); + delete options.limit; + } + + pipeline.push({ $group: { _id: 1, n: { $sum: 1 } } }); + + const result = await this.aggregate<{ n: number }>( + pipeline, + options, + ).next(); + if (result) return result.n; + return 0; + } + + async estimatedDocumentCount(): Promise { + const pipeline = [ + { $collStats: { count: {} } }, + { $group: { _id: 1, n: { $sum: "$count" } } }, + ]; + + const result = await this.aggregate<{ n: number }>(pipeline).next(); + if (result) return result.n; + return 0; + } + async insertOne(doc: Document, options?: InsertOptions) { const { insertedIds } = await this.insertMany([doc], options); return insertedIds[0]; diff --git a/tests/cases/03_curd.ts b/tests/cases/03_curd.ts index dc6ec012..a519674f 100644 --- a/tests/cases/03_curd.ts +++ b/tests/cases/03_curd.ts @@ -248,6 +248,20 @@ export default function curdTests() { assertEquals(count, 2); }); + testWithClient("testCountDocuments", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const count = await users.countDocuments({ username: "many" }); + assertEquals(count, 2); + }); + + testWithClient("testEstimatedDocumentCount", async (client) => { + const db = client.database("test"); + const users = db.collection("mongo_test_users"); + const count = await users.estimatedDocumentCount(); + assertEquals(count, 4); + }); + testWithClient("testAggregation", async (client) => { const db = client.database("test"); const users = db.collection("mongo_test_users");