Skip to content

Commit

Permalink
feat(model): add countDocuments()
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jul 2, 2018
1 parent cb2a9a8 commit 93d06a4
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 4 deletions.
32 changes: 32 additions & 0 deletions lib/model.js
Expand Up @@ -1688,6 +1688,38 @@ Model.findOne = function findOne(conditions, projection, options, callback) {
return mq.findOne(conditions, callback);
};

/**
* Counts number of matching documents in a database collection. This method
* is deprecated, use `countDocuments()` instead.
*
* ####Example:
*
* Adventure.count({ type: 'jungle' }, function (err, count) {
* if (err) ..
* console.log('there are %d jungle adventures', count);
* });
*
* @deprecated
* @param {Object} conditions
* @param {Function} [callback]
* @return {Query}
* @api public
*/

Model.countDocuments = function count(conditions, callback) {
if (typeof conditions === 'function') {
callback = conditions;
conditions = {};
}

// get the mongodb collection object
const mq = new this.Query({}, {}, this, this.collection);

callback = this.$wrapCallback(callback);

return mq.countDocuments(conditions, callback);
};

/**
* Counts number of matching documents in a database collection.
*
Expand Down
81 changes: 80 additions & 1 deletion lib/query.js
Expand Up @@ -1748,7 +1748,33 @@ Query.prototype._count = function(callback) {
};

/**
* Specifying this query as a `count` query.
* Thunk around countDocuments()
*
* @param {Function} [callback]
* @see countDocuments http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#countDocuments
* @api private
*/

Query.prototype._countDocuments = function(callback) {
try {
this.cast(this.model);
} catch (err) {
this.error(err);
}

if (this.error()) {
return callback(this.error());
}

const conds = this._conditions;
const options = this._optionsForExec();

this._collection.collection.countDocuments(conds, options, utils.tick(callback));
};

/**
* Specifies this query as a `count` query. This method is deprecated, use
* `countDocuments()` instead.
*
* Passing a `callback` executes the query.
*
Expand All @@ -1769,6 +1795,7 @@ Query.prototype._count = function(callback) {
* console.log('there are %d kittens', count);
* })
*
* @deprecated
* @param {Object} [criteria] mongodb selector
* @param {Function} [callback] optional params are (error, count)
* @return {Query} this
Expand Down Expand Up @@ -1798,6 +1825,58 @@ Query.prototype.count = function(conditions, callback) {
return this;
};

/**
* Specifies this query as a `countDocuments()` query. Behaves like `count()`,
* except for [`$where` and a couple geospatial operators](http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#countDocuments).
*
* Passing a `callback` executes the query.
*
* This function triggers the following middleware.
*
* - `countDocuments()`
*
* ####Example:
*
* const countQuery = model.where({ 'color': 'black' }).countDocuments();
*
* query.countDocuments({ color: 'black' }).count(callback);
*
* query.countDocuments({ color: 'black' }, callback);
*
* query.where('color', 'black').countDocuments(function(err, count) {
* if (err) return handleError(err);
* console.log('there are %d kittens', count);
* });
*
* @param {Object} [criteria] mongodb selector
* @param {Function} [callback] optional params are (error, count)
* @return {Query} this
* @see countDocuments http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#countDocuments
* @api public
*/

Query.prototype.countDocuments = function(conditions, callback) {
if (typeof conditions === 'function') {
callback = conditions;
conditions = undefined;
}

conditions = utils.toObject(conditions);

if (mquery.canMerge(conditions)) {
this.merge(conditions);
}

this.op = 'countDocuments';
if (!callback) {
return this;
}

this._countDocuments(callback);

return this;
};

/**
* Declares or executes a distict() operation.
*
Expand Down
10 changes: 10 additions & 0 deletions test/model.test.js
Expand Up @@ -3319,6 +3319,16 @@ describe('Model', function() {
});
});

it('countDocuments()', function() {
const BlogPost = db.model('BlogPost' + random(), bpSchema);

return BlogPost.create({ title: 'foo' }).
then(() => BlogPost.count({ title: 'foo' }).exec()).
then(count => {
assert.equal(count, 1);
});
});

it('update()', function(done) {
var col = 'BlogPost' + random();
var BlogPost = db.model(col, bpSchema);
Expand Down
12 changes: 9 additions & 3 deletions test/query.test.js
Expand Up @@ -1129,7 +1129,7 @@ describe('Query', function() {
assert.ifError(error);
M.deleteOne({ name: /Stark/ }, function(error) {
assert.ifError(error);
M.count({}, function(error, count) {
M.countDocuments({}, function(error, count) {
assert.ifError(error);
assert.equal(count, 1);
done();
Expand Down Expand Up @@ -1250,7 +1250,7 @@ describe('Query', function() {
Test.remove({ name: /Stark/ }).setOptions({ single: true }).exec(function(error, res) {
assert.ifError(error);
assert.equal(res.n, 1);
Test.count({}, function(error, count) {
Test.countDocuments({}, function(error, count) {
assert.ifError(error);
assert.equal(count, 1);
done();
Expand Down Expand Up @@ -1671,6 +1671,12 @@ describe('Query', function() {
});
});

it('ignores sort when passed to countDocuments', function() {
var Product = db.model('Product', 'Product_setOptions_test');
return Product.create({}).
then(() => Product.find().sort({_id: 1}).countDocuments({}).exec());
});

it('ignores count when passed to sort', function(done) {
var Product = db.model('Product', 'Product_setOptions_test');
Product.find().count({}).sort({_id: 1}).exec(function(error) {
Expand Down Expand Up @@ -2698,7 +2704,7 @@ describe('Query', function() {
Object.assign(query, { price: priceQuery });

yield Model.create(tests);
var count = yield Model.count(query);
var count = yield Model.countDocuments(query);
assert.strictEqual(count, 9);
});
});
Expand Down

0 comments on commit 93d06a4

Please sign in to comment.