@@ -1829,6 +1829,7 @@ var indexInformation = function(self, options, callback) {
1829
1829
* @param {ClientSession } [options.session] optional session to use for this operation
1830
1830
* @param {Collection~countCallback } [callback] The command result callback
1831
1831
* @return {Promise } returns Promise if no callback passed
1832
+ * @deprecated use countDocuments or estimatedDocumentCount instead
1832
1833
*/
1833
1834
Collection . prototype . count = function ( query , options , callback ) {
1834
1835
var args = Array . prototype . slice . call ( arguments , 0 ) ;
@@ -1839,19 +1840,36 @@ Collection.prototype.count = function(query, options, callback) {
1839
1840
return executeOperation ( this . s . topology , count , [ this , query , options , callback ] ) ;
1840
1841
} ;
1841
1842
1842
- var count = function ( self , query , options , callback ) {
1843
- var skip = options . skip ;
1844
- var limit = options . limit ;
1845
- var hint = options . hint ;
1846
- var maxTimeMS = options . maxTimeMS ;
1843
+ /**
1844
+ * Gets an estimate of the count of documents in a collection using collection metadata.
1845
+ * @method
1846
+ * @param {object } [options] Optional settings.
1847
+ * @param {number } [options.maxTimeMS] The maximum amount of time to allow the operation to run.
1848
+ * @param {Collection~countCallback } [callback] The command result callback.
1849
+ * @return {Promise } returns Promise if no callback passed.
1850
+ */
1851
+ Collection . prototype . estimatedDocumentCount = function ( options , callback ) {
1852
+ if ( typeof options === 'function' ) ( callback = options ) , ( options = { } ) ;
1853
+ options = options || { } ;
1847
1854
1848
- // Final query
1849
- var cmd = {
1850
- count : self . s . name ,
1855
+ options = typeof options . maxTimeMS === 'number' ? options : { } ;
1856
+
1857
+ return executeOperation ( this . s . topology , count , [ this , null , options , callback ] ) ;
1858
+ } ;
1859
+
1860
+ const count = function ( collection , query , options , callback ) {
1861
+ const skip = options . skip ;
1862
+ const limit = options . limit ;
1863
+ const hint = options . hint ;
1864
+ const maxTimeMS = options . maxTimeMS ;
1865
+ query = query || { } ;
1866
+
1867
+ const cmd = {
1868
+ count : collection . s . name ,
1851
1869
query : query
1852
1870
} ;
1853
1871
1854
- // Add limit, skip and maxTimeMS if defined
1872
+ // Add skip, limit, maxTimeMS, and hint if defined
1855
1873
if ( typeof skip === 'number' ) cmd . skip = skip ;
1856
1874
if ( typeof limit === 'number' ) cmd . limit = limit ;
1857
1875
if ( typeof maxTimeMS === 'number' ) cmd . maxTimeMS = maxTimeMS ;
@@ -1860,21 +1878,74 @@ var count = function(self, query, options, callback) {
1860
1878
options = shallowClone ( options ) ;
1861
1879
1862
1880
// Ensure we have the right read preference inheritance
1863
- options = getReadPreference ( self , options , self . s . db ) ;
1881
+ options = getReadPreference ( collection , options , collection . s . db ) ;
1864
1882
1865
1883
// Do we have a readConcern specified
1866
- decorateWithReadConcern ( cmd , self , options ) ;
1884
+ decorateWithReadConcern ( cmd , collection , options ) ;
1867
1885
1868
1886
// Have we specified collation
1869
- decorateWithCollation ( cmd , self , options ) ;
1887
+ decorateWithCollation ( cmd , collection , options ) ;
1870
1888
1871
1889
// Execute command
1872
- self . s . db . command ( cmd , options , function ( err , result ) {
1890
+ collection . s . db . command ( cmd , options , function ( err , result ) {
1873
1891
if ( err ) return handleCallback ( callback , err ) ;
1874
1892
handleCallback ( callback , null , result . n ) ;
1875
1893
} ) ;
1876
1894
} ;
1877
1895
1896
+ /**
1897
+ * Gets the number of documents matching the filter.
1898
+ * @param {object } [query] the query for the count
1899
+ * @param {object } [options] Optional settings.
1900
+ * @param {object } [options.collation] Specifies a collation.
1901
+ * @param {string|object } [options.hint] The index to use.
1902
+ * @param {number } [options.limit] The maximum number of document to count.
1903
+ * @param {number } [options.maxTimeMS] The maximum amount of time to allow the operation to run.
1904
+ * @param {number } [options.skip] The number of documents to skip before counting.
1905
+ * @param {Collection~countCallback } [callback] The command result callback.
1906
+ * @return {Promise } returns Promise if no callback passed.
1907
+ */
1908
+
1909
+ Collection . prototype . countDocuments = function ( query , options , callback ) {
1910
+ var args = Array . prototype . slice . call ( arguments , 0 ) ;
1911
+ callback = typeof args [ args . length - 1 ] === 'function' ? args . pop ( ) : undefined ;
1912
+ query = args . length ? args . shift ( ) || { } : { } ;
1913
+ options = args . length ? args . shift ( ) || { } : { } ;
1914
+
1915
+ return executeOperation ( this . s . topology , countDocuments , [ this , query , options , callback ] ) ;
1916
+ } ;
1917
+
1918
+ const countDocuments = function ( collection , query , options , callback ) {
1919
+ const skip = options . skip ;
1920
+ const limit = options . limit ;
1921
+ options = Object . assign ( { } , options ) ;
1922
+
1923
+ const pipeline = [ { $match : query } ] ;
1924
+
1925
+ // Add skip and limit if defined
1926
+ if ( typeof skip === 'number' ) {
1927
+ pipeline . push ( { $skip : skip } ) ;
1928
+ }
1929
+
1930
+ if ( typeof limit === 'number' ) {
1931
+ pipeline . push ( { $limit : limit } ) ;
1932
+ }
1933
+
1934
+ pipeline . push ( { $group : { _id : null , n : { $sum : 1 } } } ) ;
1935
+
1936
+ delete options . limit ;
1937
+ delete options . skip ;
1938
+
1939
+ // TODO: look out for how this plays into operations refactor
1940
+ collection . aggregate ( pipeline , options , function ( err , result ) {
1941
+ if ( err ) return handleCallback ( callback , err ) ;
1942
+ result
1943
+ . toArray ( )
1944
+ . then ( docs => handleCallback ( callback , null , docs [ 0 ] . n ) )
1945
+ . catch ( e => handleCallback ( e ) ) ;
1946
+ } ) ;
1947
+ } ;
1948
+
1878
1949
/**
1879
1950
* The distinct command returns returns a list of distinct values for the given key across a collection.
1880
1951
* @method
0 commit comments