@@ -192,57 +192,48 @@ Object.defineProperty(Collection.prototype, 'hint', {
192192/**
193193 * Creates a cursor for a query that can be used to iterate over results from MongoDB
194194 * @method
195- * @param {object } query The cursor query object.
196- * @param {Object } [options] Optional settings
195+ * @param {object } [query={}] The cursor query object.
196+ * @param {object } [options=null] Optional settings.
197+ * @param {number } [options.limit=0] Sets the limit of documents returned in the query.
198+ * @param {(array|object) } [options.sort=null] Set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
199+ * @param {object } [options.projection=null] The fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
200+ * @param {object } [options.fields=null] **Deprecated** Use `options.projection` instead
201+ * @param {number } [options.skip=0] Set to skip N documents ahead in your query (useful for pagination).
202+ * @param {Object } [options.hint=null] Tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
203+ * @param {boolean } [options.explain=false] Explain the query instead of returning the data.
204+ * @param {boolean } [options.snapshot=false] Snapshot query.
205+ * @param {boolean } [options.timeout=false] Specify if the cursor can timeout.
206+ * @param {boolean } [options.tailable=false] Specify if the cursor is tailable.
207+ * @param {number } [options.batchSize=0] Set the batchSize for the getMoreCommand when iterating over the query results.
208+ * @param {boolean } [options.returnKey=false] Only return the index key.
209+ * @param {number } [options.maxScan=null] Limit the number of items to scan.
210+ * @param {number } [options.min=null] Set index bounds.
211+ * @param {number } [options.max=null] Set index bounds.
212+ * @param {boolean } [options.showDiskLoc=false] Show disk location of results.
213+ * @param {string } [options.comment=null] You can put a $comment field on a query to make looking in the profiler logs simpler.
214+ * @param {boolean } [options.raw=false] Return document results as raw BSON buffers.
215+ * @param {boolean } [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
216+ * @param {boolean } [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
217+ * @param {boolean } [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
218+ * @param {(ReadPreference|string) } [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
219+ * @param {boolean } [options.partial=false] Specify if the cursor should return partial results when querying against a sharded system
220+ * @param {number } [options.maxTimeMS=null] Number of miliseconds to wait before aborting the query.
221+ * @param {object } [options.collation=null] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
197222 * @param {ClientSession } [options.session] optional session to use for this operation
198223 * @throws {MongoError }
199224 * @return {Cursor }
200225 */
201- Collection . prototype . find = function ( ) {
202- var options ,
203- args = Array . prototype . slice . call ( arguments , 0 ) ,
204- has_callback = typeof args [ args . length - 1 ] === 'function' ,
205- has_weird_callback = typeof args [ 0 ] === 'function' ,
206- callback = has_callback ? args . pop ( ) : has_weird_callback ? args . shift ( ) : null ,
207- len = args . length ,
208- selector = len >= 1 ? args [ 0 ] : { } ,
209- fields = len >= 2 ? args [ 1 ] : undefined ;
210-
211- if ( len === 1 && has_weird_callback ) {
212- // backwards compat for callback?, options case
213- selector = { } ;
214- options = args [ 0 ] ;
215- }
216-
217- if ( len === 2 && fields !== undefined && ! Array . isArray ( fields ) ) {
218- var fieldKeys = Object . keys ( fields ) ;
219- var is_option = false ;
220-
221- for ( var i = 0 ; i < fieldKeys . length ; i ++ ) {
222- if ( testForFields [ fieldKeys [ i ] ] != null ) {
223- is_option = true ;
224- break ;
225- }
226- }
227-
228- if ( is_option ) {
229- options = fields ;
230- fields = undefined ;
231- } else {
232- options = { } ;
233- }
234- } else if ( len === 2 && Array . isArray ( fields ) && ! Array . isArray ( fields [ 0 ] ) ) {
235- var newFields = { } ;
236- // Rewrite the array
237- for ( i = 0 ; i < fields . length ; i ++ ) {
238- newFields [ fields [ i ] ] = 1 ;
226+ Collection . prototype . find = function ( query , options , callback ) {
227+ let selector = query ;
228+ // figuring out arguments
229+ if ( typeof callback !== 'function' ) {
230+ if ( typeof options === 'function' ) {
231+ callback = options ;
232+ options = undefined ;
233+ } else if ( options == null ) {
234+ callback = typeof selector === 'function' ? selector : undefined ;
235+ selector = typeof selector === 'object' ? selector : undefined ;
239236 }
240- // Set the fields
241- fields = newFields ;
242- }
243-
244- if ( 3 === len ) {
245- options = args [ 2 ] ;
246237 }
247238
248239 // Ensure selector is not null
@@ -264,50 +255,24 @@ Collection.prototype.find = function() {
264255 }
265256 }
266257
267- // Validate correctness of the field selector
268- object = fields ;
269- if ( Buffer . isBuffer ( object ) ) {
270- object_size = object [ 0 ] | ( object [ 1 ] << 8 ) | ( object [ 2 ] << 16 ) | ( object [ 3 ] << 24 ) ;
271- if ( object_size !== object . length ) {
272- error = new Error (
273- 'query fields raw message size does not match message header size [' +
274- object . length +
275- '] != [' +
276- object_size +
277- ']'
278- ) ;
279- error . name = 'MongoError' ;
280- throw error ;
281- }
282- }
283-
284258 // Check special case where we are using an objectId
285259 if ( selector != null && selector . _bsontype === 'ObjectID' ) {
286260 selector = { _id : selector } ;
287261 }
288262
289- // If it's a serialized fields field we need to just let it through
290- // user be warned it better be good
291- if ( options && options . fields && ! Buffer . isBuffer ( options . fields ) ) {
292- fields = { } ;
263+ if ( ! options ) options = { } ;
293264
294- if ( Array . isArray ( options . fields ) ) {
295- if ( ! options . fields . length ) {
296- fields [ '_id' ] = 1 ;
297- } else {
298- var l = options . fields . length ;
265+ let projection = options . projection || options . fields ;
299266
300- for ( i = 0 ; i < l ; i ++ ) {
301- fields [ options . fields [ i ] ] = 1 ;
302- }
303- }
304- } else {
305- fields = options . fields ;
306- }
267+ if ( projection && ! Buffer . isBuffer ( projection ) && Array . isArray ( projection ) ) {
268+ projection = projection . length
269+ ? projection . reduce ( ( result , field ) => {
270+ result [ field ] = 1 ;
271+ return result ;
272+ } , { } )
273+ : { _id : 1 } ;
307274 }
308275
309- if ( ! options ) options = { } ;
310-
311276 var newOptions = { } ;
312277
313278 // Make a shallow copy of the collection options
@@ -323,13 +288,11 @@ Collection.prototype.find = function() {
323288 }
324289
325290 // Unpack options
326- newOptions . skip = len > 3 ? args [ 2 ] : options . skip ? options . skip : 0 ;
327- newOptions . limit = len > 3 ? args [ 3 ] : options . limit ? options . limit : 0 ;
328- newOptions . raw =
329- options . raw != null && typeof options . raw === 'boolean' ? options . raw : this . s . raw ;
291+ newOptions . skip = options . skip ? options . skip : 0 ;
292+ newOptions . limit = options . limit ? options . limit : 0 ;
293+ newOptions . raw = typeof options . raw === 'boolean' ? options . raw : this . s . raw ;
330294 newOptions . hint = options . hint != null ? normalizeHintField ( options . hint ) : this . s . collectionHint ;
331- newOptions . timeout =
332- len === 5 ? args [ 4 ] : typeof options . timeout === 'undefined' ? undefined : options . timeout ;
295+ newOptions . timeout = typeof options . timeout === 'undefined' ? undefined : options . timeout ;
333296 // // If we have overridden slaveOk otherwise use the default db setting
334297 newOptions . slaveOk = options . slaveOk != null ? options . slaveOk : this . s . db . slaveOk ;
335298
@@ -372,26 +335,7 @@ Collection.prototype.find = function() {
372335 }
373336 }
374337
375- // Format the fields
376- var formatFields = function ( fields ) {
377- var object = { } ;
378- if ( Array . isArray ( fields ) ) {
379- for ( var i = 0 ; i < fields . length ; i ++ ) {
380- if ( Array . isArray ( fields [ i ] ) ) {
381- object [ fields [ i ] [ 0 ] ] = fields [ i ] [ 1 ] ;
382- } else {
383- object [ fields [ i ] [ 0 ] ] = 1 ;
384- }
385- }
386- } else {
387- object = fields ;
388- }
389-
390- return object ;
391- } ;
392-
393- // Special treatment for the fields selector
394- if ( fields ) findCommand . fields = formatFields ( fields ) ;
338+ if ( projection ) findCommand . fields = projection ;
395339
396340 // Add db object to the new options
397341 newOptions . db = this . s . db ;
@@ -1361,7 +1305,8 @@ define.classMethod('save', { callback: true, promise: true });
13611305 * @param {object } [options=null] Optional settings.
13621306 * @param {number } [options.limit=0] Sets the limit of documents returned in the query.
13631307 * @param {(array|object) } [options.sort=null] Set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
1364- * @param {object } [options.fields=null] The fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
1308+ * @param {object } [options.projection=null] The fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
1309+ * @param {object } [options.fields=null] **Deprecated** Use `options.projection` instead
13651310 * @param {number } [options.skip=0] Set to skip N documents ahead in your query (useful for pagination).
13661311 * @param {Object } [options.hint=null] Tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
13671312 * @param {boolean } [options.explain=false] Explain the query instead of returning the data.
@@ -2253,7 +2198,8 @@ define.classMethod('findOneAndUpdate', { callback: true, promise: true });
22532198 * @param {boolean } [options.remove=false] Set to true to remove the object before returning.
22542199 * @param {boolean } [options.upsert=false] Perform an upsert operation.
22552200 * @param {boolean } [options.new=false] Set to true if you want to return the modified object rather than the original. Ignored for remove.
2256- * @param {object } [options.fields=null] Object containing the field projection for the result returned from the operation.
2201+ * @param {object } [options.projection=null] Object containing the field projection for the result returned from the operation.
2202+ * @param {object } [options.fields=null] **Deprecated** Use `options.projection` instead
22572203 * @param {ClientSession } [options.session] optional session to use for this operation
22582204 * @param {Collection~findAndModifyCallback } [callback] The command result callback
22592205 * @return {Promise } returns Promise if no callback passed
@@ -2297,8 +2243,10 @@ var findAndModify = function(self, query, sort, doc, options, callback) {
22972243 queryObject . remove = options . remove ? true : false ;
22982244 queryObject . upsert = options . upsert ? true : false ;
22992245
2300- if ( options . fields ) {
2301- queryObject . fields = options . fields ;
2246+ const projection = options . projection || options . fields ;
2247+
2248+ if ( projection ) {
2249+ queryObject . fields = projection ;
23022250 }
23032251
23042252 if ( options . arrayFilters ) {
@@ -3272,39 +3220,4 @@ var getReadPreference = function(self, options, db) {
32723220 return options ;
32733221} ;
32743222
3275- var testForFields = {
3276- limit : 1 ,
3277- sort : 1 ,
3278- fields : 1 ,
3279- skip : 1 ,
3280- hint : 1 ,
3281- explain : 1 ,
3282- snapshot : 1 ,
3283- timeout : 1 ,
3284- tailable : 1 ,
3285- tailableRetryInterval : 1 ,
3286- numberOfRetries : 1 ,
3287- awaitdata : 1 ,
3288- awaitData : 1 ,
3289- exhaust : 1 ,
3290- batchSize : 1 ,
3291- returnKey : 1 ,
3292- maxScan : 1 ,
3293- min : 1 ,
3294- max : 1 ,
3295- showDiskLoc : 1 ,
3296- comment : 1 ,
3297- raw : 1 ,
3298- readPreference : 1 ,
3299- partial : 1 ,
3300- read : 1 ,
3301- dbName : 1 ,
3302- oplogReplay : 1 ,
3303- connection : 1 ,
3304- maxTimeMS : 1 ,
3305- transforms : 1 ,
3306- collation : 1 ,
3307- noCursorTimeout : 1
3308- } ;
3309-
33103223module . exports = Collection ;
0 commit comments