UNPKG

@carbon-io/leafnode

Version:
902 lines (841 loc) 50 kB
var assert = require('assert') var _ = require('lodash') var util = require('./util') var syncOrAsync = util.syncOrAsync var Cursor = require('./cursor').Cursor var errors = require('./errors') /*************************************************************************************************** * @namespace leafnode */ /*************************************************************************************************** * @class Collection * @description This constructor should not be called directly. Use DB.getCollection() * @memberof leafnode */ function Collection(db, collection) { /***************************************************************************** * @property {DB} db -- xxx */ this.db = db /***************************************************************************** * @property {mongodb.Collection} _collection -- xxx */ this._collection = collection } /*************************************************************************************************** * @method count * @description count description * @param {Object} query -- xxx * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * * @returns {number} -- The number of documents in this collection */ Collection.prototype.count = function(query, cb) { return syncOrAsync(this._collection, 'count', [query], undefined, cb) } /*************************************************************************************************** * @method createIndex * @description Creates an index on the db and collection collection. * @param {string|object} fieldOrSpec -- Defines the index. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.unique=false] -- Creates an unique index. * @param {boolean} [options.sparse=false] -- Creates a sparse index. * @param {boolean} [options.background=false] -- Creates the index in the background, yielding whenever possible. * @param {boolean} [options.dropDups=false] -- A unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value * @param {number} [options.min=null] -- For geospatial indexes set the lower bound for the co-ordinates. * @param {number} [options.max=null] -- For geospatial indexes set the high bound for the co-ordinates. * @param {number} [options.v=null] -- Specify the format version of the indexes. * @param {number} [options.expireAfterSeconds=null] -- Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) * @param {number} [options.name=null] -- Override the autogenerated index name (useful if the resulting name is larger than 128 bytes) * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {string} -- returns index name * @throws {Error} -- xxx */ Collection.prototype.createIndex = function(fieldOrSpec, options, cb) { return syncOrAsync(this._collection, 'createIndex', [fieldOrSpec, options], undefined, cb) } /*************************************************************************************************** * @method distinct * @description The distinct command returns returns a list of distinct values for the given key across a collection. * @param {string} key -- Field of the document to find distinct values for. * @param {object} query -- The query for filtering the set of documents to which we apply the distinct filter. * @param {object} [options=null] -- Optional settings. * @param {ReadPreference|string} [options.readPreference=null] -- The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {xxx} -- returns array of distinct values * @throws {Error} -- xxx */ Collection.prototype.distinct = function(key, query, options, cb) { return syncOrAsync(this._collection, 'distinct', [key, query, options], undefined, cb) } /*************************************************************************************************** * @method drop * @description Drop the collection from the database, removing it permanently. New accesses will create a new collection. * @param {object} [options=null] -- Optional settings (not currently used) * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- returns true if collection dropped, false otherwise * @throws {Error} -- xxx */ Collection.prototype.drop = function(options, cb) { return syncOrAsync(this._collection, 'drop', [options], undefined, cb) } /*************************************************************************************************** * @method dropIndex * @description Drops an index from this collection. * @param {string} indexName -- Name of the index to drop. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {Object} -- returns object containing ok:0|1 and nIndexesWas:total indexes * @throws {Error} -- xxx */ Collection.prototype.dropIndex = function(indexName, options, cb) { return syncOrAsync(this._collection, 'dropIndex', [indexName, options], undefined, cb) } /*************************************************************************************************** * @method dropAllIndexesa * @description Drops all indexes from this collection. * @deprecated use dropIndexes * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- returns true if removed, false otherwise * @throws {Error} -- xxx */ Collection.prototype.dropAllIndexes = function(cb) { return syncOrAsync(this._collection, 'dropIndexes', [], undefined, cb) } /*************************************************************************************************** * @method dropIndexes * @description Drops all indexes from this collection. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- returns true if removed, false otherwise * @throws {Error} -- xxx */ Collection.prototype.dropIndexes = function(cb) { return syncOrAsync(this._collection, 'dropIndexes', [], undefined, cb) } /**************************************************************************************************** * each TODO: do we want this at the collection level? */ /*************************************************************************************************** * @method ensureIndex * @description Ensures that an index exists, if it does not it creates it * @deprecated use createIndexes instead * @param {string|object} fieldOrSpec -- Defines the index. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] --The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.unique=false] -- Creates an unique index. * @param {boolean} [options.sparse=false] -- Creates a sparse index. * @param {boolean} [options.background=false] -- Creates the index in the background, yielding whenever possible. * @param {boolean} [options.dropDups=false] -- A unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value * @param {number} [options.min=null] -- For geospatial indexes set the lower bound for the co-ordinates. * @param {number} [options.max=null] -- For geospatial indexes set the high bound for the co-ordinates. * @param {number} [options.v=null] -- Specify the format version of the indexes. * @param {number} [options.expireAfterSeconds=null] -- Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) * @param {number} [options.name=null] -- Override the autogenerated index name (useful if the resulting name is larger than 128 bytes) * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {string} -- returns index name * @throws {Error} -- xxx */ Collection.prototype.ensureIndex = function(fieldOrSpec, options, cb) { return syncOrAsync(this._collection, 'ensureIndex', [fieldOrSpec, options], undefined, cb) } /*************************************************************************************************** * Creates a cursor for a query that can be used to iterate over results from MongoDB. Note that query options are * exposed through the Cursor api. * @method find * @description Creates a cursor for a query that can be used to iterate over results from MongoDB. Note that query options are * exposed through the Cursor api. * @param {object} query -- The cursor query object. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {Cursor} -- xxx * @throws {Error} -- xxx */ Collection.prototype.find = function(query, cb) { var curs = new Cursor(this._collection.find.apply(this._collection, [query])) return cb ? cb(undefined, curs) : curs } /*************************************************************************************************** * @method findAndModify * @description Find and update a document. * @param {object} query -- Query object to locate the object to modify. * @param {array} sort -- If multiple docs match, choose the first one in the specified sort order as the object to manipulate. * @param {object} doc -- The fields/vals to be updated. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.remove=false] -- Set to true to remove the object before returning. * @param {boolean} [options.upsert=false] -- Perform an upsert operation. * @param {boolean} [options.new=false] -- Set to true if you want to return the modified object rather than the original. Ignored for remove. * @param {object} [options.fields=null] -- Object containing the field projection for the result returned from the operation. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~findAndModifyWriteOpResult * @deprecated use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead * @throws {Error} -- xxx */ Collection.prototype.findAndModify = function(query, sort, doc, options, cb) { return syncOrAsync( this._collection, 'findAndModify', [query, sort, doc, options], undefined, cb ) } /*************************************************************************************************** * @method findOne * @description Fetches the first document that matches the query * @param {object} query -- Query for find Operation * @param {object} [options=null] -- Optional settings. * @param {number} [options.limit=0] -- Sets the limit of documents returned in the query. * @param {array|object} [options.sort=null] -- Set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc. * @param {object} [options.fields=null] -- The fields to return in the query. Object of fields to include or exclude (not both), {'a':1} * @param {number} [options.skip=0] -- Set to skip N documents ahead in your query (useful for pagination). * @param {Object} [options.hint=null] -- Tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1} * @param {boolean} [options.explain=false] -- Explain the query instead of returning the data. * @param {boolean} [options.snapshot=false] -- Snapshot query. * @param {boolean} [options.timeout=false] -- Specify if the cursor can timeout. * @param {boolean} [options.tailable=false] -- Specify if the cursor is tailable. * @param {number} [options.batchSize=0] -- Set the batchSize for the getMoreCommand when iterating over the query results. * @param {boolean} [options.returnKey=false] -- Only return the index key. * @param {number} [options.maxScan=null] -- Limit the number of items to scan. * @param {number} [options.min=null] -- Set index bounds. * @param {number} [options.max=null] -- Set index bounds. * @param {boolean} [options.showDiskLoc=false] -- Show disk location of results. * @param {string} [options.comment=null] -- You can put a $comment field on a query to make looking in the profiler logs simpler. * @param {boolean} [options.raw=false] -- Return all BSON documents as Raw Buffer documents. * @param {ReadPreference|string} [options.readPreference=null] -- The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {boolean} [options.partial=false] -- Specify if the cursor should return partial results when querying against a sharded system * @param {number} [options.maxTimeMS=null] -- Number of miliseconds to wait before aborting the query. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @returns {object} -- returns the doc if found or null if not found * @throws {Error} -- xxx */ Collection.prototype.findOne = function(query, options, cb) { return syncOrAsync( this._collection, 'findOne', [query, options], undefined, cb) } /*************************************************************************************************** * @method findOneAndDelete * @description Find a document and delete it in one atomic operation, requires a write lock for the duration of the operation. * @param {object} query -- Document selection query. * @param {object} [options=null] -- Optional settings. * @param {object} [options.projection=null] -- Limits the fields to return for all matching documents. * @param {object} [options.sort=null] -- Determines which document the operation modifies if the query selects multiple documents. * @param {number} [options.maxTimeMS=null] -- The maximum amount of time to allow the query to run. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @returns {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~findAndModifyWriteOpResult * @throws {Error} -- xxx */ Collection.prototype.findOneAndDelete = function(query, options, cb) { return syncOrAsync(this._collection, 'findOneAndDelete', [query, options], undefined, cb) } /*************************************************************************************************** * @method findOneAndReplace * @description Find a document and replace it in one atomic operation, requires a write lock for the duration of the operation. * @param {object} query -- Document selection query. * @param {object} replacement -- Document replacing the matching document. * @param {object} [options=null] -- Optional settings. * @param {object} [options.projection=null] -- Limits the fields to return for all matching documents. * @param {object} [options.sort=null] -- Determines which document the operation modifies if the query selects multiple documents. * @param {number} [options.maxTimeMS=null] -- The maximum amount of time to allow the query to run. * @param {boolean} [options.upsert=false] -- Upsert the document if it does not exist. * @param {boolean} [options.returnOriginal=true] -- When false, returns the updated document rather than the original. The default is true. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @returns {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~findAndModifyWriteOpResult * @throws {Error} -- xxx */ Collection.prototype.findOneAndReplace = function(query, replacement, options, cb) { return syncOrAsync( this._collection, 'findOneAndReplace', [query, replacement, options], undefined, cb) } /*************************************************************************************************** * @method findOneAndUpdatea * @description Find a document and update it in one atomic operation, requires a write lock for the duration of the operation. * @param {object} query -- Document selection query. * @param {object} update -- Update operations to be performed on the document * @param {object} [options=null] -- Optional settings. * @param {object} [options.projection=null] -- Limits the fields to return for all matching documents. * @param {object} [options.sort=null] -- Determines which document the operation modifies if the query selects multiple documents. * @param {number} [options.maxTimeMS=null] -- The maximum amount of time to allow the query to run. * @param {boolean} [options.upsert=false] -- Upsert the document if it does not exist. * @param {boolean} [options.returnOriginal=true] -- When false, returns the updated document rather than the original. The default is true. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @returns {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~findAndModifyWriteOpResult * @throws {Error} -- xxx */ Collection.prototype.findOneAndUpdate = function(query, update, options, cb) { return syncOrAsync(this._collection, 'findOneAndUpdate', [query, update, options], undefined, cb) } /** * findById * * @param {ObjectId | String | Number} id; // TODO: lookup allowed types for _id * * @returns {Object} the matching document * @throws {Error} */ // -----------------------^ // TODO: DO WE WANT THIS? | // -----------------------| /*************************************************************************************************** * @method getIndexes * @description Retrieve all the indexes on the collection. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {array} -- returns array of indexes each with name, namespace and key * @throws {Error} -- xxx */ Collection.prototype.getIndexes = function(cb) { return syncOrAsync(this._collection, 'indexes', [], undefined, cb) } /*************************************************************************************************** * @method group * @description Run a group command across a collection * @param {object|array|function|code} keys -- An object, array or function expressing the keys to group by. * @param {object} condition -- An optional condition that must be true for a row to be considered. * @param {object} initial -- Initial value of the aggregation counter object. * @param {function|Code} reduce -- The reduce function aggregates (reduces) the objects iterated * @param {function|Code} finalize -- An optional function to be run on each item in the result set just before the item is returned. * @param {boolean} command -- Specify if you wish to run using the internal group command or using eval, default is true. * @param {object} [options=null] -- Optional settings. * @param {ReadPreference|string} [options.readPreference=null] -- The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {array} -- returns results of the group command * @throws {Error} -- xxx */ // TODO (better as one cmd object?) Collection.prototype.group = function(keys, condition, initial, reduce, finalize, command, options, cb) { return syncOrAsync( this._collection, 'group', [ keys, condition, initial, reduce, finalize, command, options ], undefined, cb) } /*************************************************************************************************** * @method indexInformationa * @description Retrieves this collection's index information. * @param {object} [options=null] -- Optional settings. * @param {boolean} [options.full=false] -- Returns the full raw index information. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- The result object. * @throws {Error} -- xxx */ Collection.prototype.indexInformation = function(options, cb) { return syncOrAsync(this._collection, 'indexInformation', [options], undefined, cb) } /*************************************************************************************************** * @method insert * @description Inserts a single document or an array of documents into MongoDB. * @param {object|object} -- docs Documents to insert. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.serializeFunctions=false] -- Serialize functions on any object. * @param {boolean} [options.forceServerObjectId=false] -- Force server to assign _id values instead of driver. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~insertWriteOpResult * @deprecated Use {@link insertOne}, {@link insertMany} or {@link bulkWrite}. * @throws {Error} -- xxx */ Collection.prototype.insert = function(docs, options, cb) { return syncOrAsync(this._collection, 'insert', [docs, options], undefined, cb) } /*************************************************************************************************** * @method insertMany * @description Inserts an array of documents into MongoDB. * @param {object} docs -- Documents to insert. * @param {object} [options=null] -- Optional settings. * @param {(number|string)} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.serializeFunctions=false] -- Serialize functions on any object. * @param {boolean} [options.forceServerObjectId=false] -- Force server to assign _id values instead of driver. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~insertWriteOpResult * @throws {Error} -- xxx */ Collection.prototype.insertMany = function(docs, options, cb) { return syncOrAsync(this._collection, 'insertMany', [docs, options], undefined, cb) } /*************************************************************************************************** * @method insertOnea * @description Inserts a single document into MongoDB. * @param {object} doc -- Document to insert. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.serializeFunctions=false] -- Serialize functions on any object. * @param {boolean} [options.forceServerObjectId=false] -- Force server to assign _id values instead of driver. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~insertOneWriteOpResult * @throws {Error} */ Collection.prototype.insertOne = function(doc, options, cb) { return syncOrAsync(this._collection, 'insertOne', [doc, options], undefined, cb) } /*************************************************************************************************** * @method isCappeda * @description Returns if the collection is a capped collection * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- returns true if capped, false otherwise * @throws {Error} */ Collection.prototype.isCapped = function isCapped(cb) { return syncOrAsync(this._collection, 'isCapped', [], undefined, cb) } /*************************************************************************************************** * @method mapReduce * @description Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection. * @param {function|string} map -- The mapping function. * @param {function|string} reduce -- The reduce function. * @param {object} [options=null] -- Optional settings. * @param {ReadPreference|string} [options.readPreference=null] -- The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). * @param {object} [options.out=null] -- Sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}* * @param {object} [options.query=null] -- Query filter object. * @param {object} [options.sort=null] -- Sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces. * @param {number} [options.limit=null] -- Number of objects to return from collection. * @param {boolean} [options.keeptemp=false] -- Keep temporary data. * @param {function|string} [options.finalize=null] -- Finalize function. * @param {object} [options.scope=null] -- Can pass in variables that can be access from map/reduce/finalize. * @param {boolean} [options.jsMode=false] -- It is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X. * @param {boolean} [options.verbose=false] -- Provide statistics on job execution time. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error} * @return {Collection} -- returns the temporary collection with results of the mapReduce */ Collection.prototype.mapReduce = function mapReduce(map, reduce, options, cb) { var self = this return syncOrAsync(this._collection, 'mapReduce', [map, reduce, options], function(result) { return new Collection(self.db, result) }, cb) } /*************************************************************************************************** * @method reIndex * @description Reindex all indexes on the collection Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- returns true if reindex succeeded, false otherwise * @throws {Error} */ Collection.prototype.reIndex = function(cb) { return syncOrAsync(this._collection, 'reIndex', [], undefined, cb) } /*************************************************************************************************** * @method save * @description Save a document. Simple full document replacement function. Not recommended for efficiency, * use atomic operators and update instead for more efficient operations. * @param {object} doc -- Document to save * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult * @throws {Error} */ Collection.prototype.save = function(doc, options, cb) { return syncOrAsync(this._collection, 'save', [doc, options], undefined, cb) } /*************************************************************************************************** * @method stats * @description Get all the collection statistics. * @param {object} [options=null] -- Optional settings. * @param {number} [options.scale=null] -- Divide the returned sizes by scale value. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- returns collection statistics * @throws {Error} */ Collection.prototype.stats = function(options, cb) { return syncOrAsync(this._collection, 'stats', [options], undefined, cb) } /*************************************************************************************************** * @method update * @description Updates documents. * @param {object} query -- The selector for the update operation. * @param {object} doc -- The update document. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.upsert=false] -- Update operation is an upsert. * @param {boolean} [options.multi=false] -- Update one/all documents with operation. * @throws {Error} * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~updateWriteOpResult * @deprecated Use {@link updateOne}, {@link updateMany} or {@link bulkWrite}. */ Collection.prototype.update = function(query, doc, options, cb) { return syncOrAsync( this._collection, 'update', [query, doc, options], undefined, cb) } /*************************************************************************************************** * @method updateOne * @description Update a single document. * @param {object} query -- The query used to select the document to update * @param {object} update -- The update operations to be applied to the document * @param {object} [options=null] -- Optional settings. * @param {boolean} [options.upsert=false] -- Update operation is an upsert. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~updateWriteOpResult * @throws {Error} */ Collection.prototype.updateOne = function(query, update, options, cb) { return syncOrAsync(this._collection, 'updateOne', [query, update, options], undefined, cb) } /*************************************************************************************************** * @method updateMany * @description Update multiple documents. * @param {object} query -- The query used to select the document to update * @param {object} update -- The update operations to be applied to the document * @param {object} [options=null] -- Optional settings. * @param {boolean} [options.upsert=false] -- Update operation is an upsert. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~updateWriteOpResult * @throws {Error} */ Collection.prototype.updateMany = function(query, update, options, cb) { return syncOrAsync( this._collection, 'updateMany', [query, update, options], undefined, cb) } /*************************************************************************************************** * @method remove * @description Remove one or many documents. * @param {object} selector -- The selector for the update operation. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.single=false] -- Removes the first document found. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~WriteOpResult * @deprecated Use {@link deleteOne}, {@link deleteMany} or {@link bulkWrite}. * @throws {Error} */ Collection.prototype.remove = function(selector, options, cb) { return syncOrAsync(this._collection, 'remove', [selector, options], undefined, cb) } /*************************************************************************************************** * @method deleteOne * @description Delete a single document. * @param {object} selector -- The selector used to select the document to delete * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~deleteWriteOpResult * @throws {Error} */ Collection.prototype.deleteOne = function(selector, options, cb) { return syncOrAsync(this._collection, 'deleteOne', [selector, options], undefined, cb) } /*************************************************************************************************** * @method removeOne * @description Remove a single document. * @param {object} selector -- The selector used to select the document to remove * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~deleteWriteOpResult * @deprecated Use {@link deleteOne}, {@link deleteMany} or {@link bulkWrite}. * @throws {Error} */ Collection.prototype.removeOne = function(selector, options, cb) { return this.deleteOne.apply(this, arguments) } /*************************************************************************************************** * @method deleteMany * @description Delete multiple documents. * @param {object} selector -- The Filter used to select the documents to delete * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~deleteWriteOpResult * @throws {Error} */ Collection.prototype.deleteMany = function(selector, options, cb) { return syncOrAsync(this._collection, 'deleteMany', [selector, options], undefined, cb) } /*************************************************************************************************** * @method removeMany * @description Remove multiple documents. * @param {object} selector -- The Filter used to select the documents to remove * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- see: http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#~deleteWriteOpResult * @deprecated Use {@link deleteOne}, {@link deleteMany} or {@link bulkWrite}. * @throws {Error} */ Collection.prototype.removeMany = function(selector, options, cb) { return this.deleteMany.apply(this, arguments) } /** * Rename the collection. * * @method * @param {string} newName New name of of the collection. * @param {object} [options=null] Optional settings. * @param {boolean} [options.dropTarget=false] Drop the target name collection if it previously exists. * @param {Collection~collectionResultCallback} [callback] The results callback * @return {Promise} returns Promise if no callback passed */ Collection.prototype.rename = function(newName, options, cb) { var self = this return syncOrAsync(this._collection, 'rename', [newName, options], function(result) { return new Collection(self.db, result) }, cb) } // ----------------------------------------------------------------------------- // object methods // ----------------------------------------------------------------------------- /*************************************************************************************************** * @method insertObject * @description Inserts a single document into MongoDB. * @param {object} doc -- Document to insert. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.serializeFunctions=false] -- Serialize functions on any object. * @param {boolean} [options.forceServerObjectId=false] -- Force server to assign _id values instead of driver. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- The inserted document. * @throws {Error} */ Collection.prototype.insertObject = function(doc, options, cb) { return syncOrAsync(this, 'insertOne', [doc, options], function(result) { if (result.insertedCount !== 1) { throw new Error(result.insertedCount + ' documents inserted, expected 1') } return result.ops[0] }, cb) } /*************************************************************************************************** * @method insertObjects * @description Inserts an array of documents into MongoDB. * @param {object} docs -- Documents to insert. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {boolean} [options.serializeFunctions=false] -- Serialize functions on any object. * @param {boolean} [options.forceServerObjectId=false] -- Force server to assign _id values instead of driver. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {object} -- The inserted documents. * @throws {Error} */ Collection.prototype.insertObjects = function(docs, options, cb) { return syncOrAsync(this, 'insertMany', [docs, options], function(result) { if (result.insertedCount !== docs.length) { // XXX: is this possible? var err = new Error(result.insertedCount + ' documents inserted, expected ' + docs.length) err.docs = result.ops throw err } return result.ops }, cb) } /*************************************************************************************************** * @method saveObject * @description Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic * operators and update instead for more efficient operations. * XXX: this only seems to report "upsert"s appropriately when you set the _id explicitly... * @param {object} doc -- Document to save. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @return {boolean} -- Returns true iff save resulted in an upsert. * @throws {Error} -- If exactly 1 document is not saved. */ Collection.prototype.saveObject = function(doc, options, cb) { return syncOrAsync(this, 'save', [doc, options], function(result) { if (result.result.upserted && result.result.upserted.length > 0) { // Save resulted in upsert return true // We return true to indicate upsert } if (result.result.n === 0) { throw new Error(`Unable to save document with _id ${doc._id}`) } if (result.result.n !== 1) { throw new Error(`Saved ${result.result.n} documents. Expected 1`) } return false // We are successful, but return false to indicate this is not an upsert }, cb) } /*************************************************************************************************** * @method updateObject * @description Update a single document. * @param {xxx} _id -- The _id of the doc to update. * @param {object} update -- The update operations to be applied to the document. * @param {object} [options=null] -- Optional settings. * @param {boolean} [options.upsert=false] -- Update operation is an upsert. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} */ Collection.prototype.updateObject = function(_id, update, options, cb) { if (_.isNil(_id)) { var err = new Error('_id required') if (cb) { return cb(err) } throw err } syncOrAsync(this._collection, 'updateOne', [{_id: _id}, update, options], function(result) { if (result.matchedCount + result.upsertedCount != 1) { throw new errors.LeafnodeObjectSetUpdateError( 'UpdateObject failed to update or upsert the document', 1, result.matchedCount, result.modifiedCount, result.upsertedCount) } }, cb) } /*************************************************************************************************** * @method updateObjects * @description Update multiple documents. * @param {xxx} _ids -- The _ids of the docs to update. * @param {object} update -- The update operations to be applied to the document. * @param {object} [options=null] -- Optional settings. * @param {boolean} [options.upsert=false] -- Update operation is an upsert. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} */ Collection.prototype.updateObjects = function(_ids, update, options, cb) { if (!_.isArray(_ids)) { _ids = [_ids] } if (_ids.length > 1 && 'upsert' in (options || {})) { throw new TypeError('updateObjects cannot upsert with multiple _ids present') } if (_.some(_ids, function(_id) { return _.isNil(_id) })) { var err = new Error('_ids required') if (cb) { return cb(err) } throw err } var query = _ids.length === 1 ? {_id: _ids[0]} : {_id: {'$in': _ids}} syncOrAsync(this._collection, 'updateMany', [query, update, options], function(result) { if (result.matchedCount + result.upsertedCount != _ids.length) { throw new errors.LeafnodeObjectSetUpdateError( 'UpdateObjects failed to update one or more documents', _ids.length, result.matchedCount, result.modifiedCount, result.upsertedCount) } }, cb) } /*************************************************************************************************** * @method deleteObject * @description Delete a single document. * @param {xxx} _id -- The _id of the doc to delete. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} */ Collection.prototype.deleteObject = function(_id, options, cb) { if (_.isNil(_id)) { var err = new Error('_id required') if (cb) { return cb(err) } throw err } syncOrAsync(this._collection, 'deleteOne', [{_id: _id}, options], function(result) { if (result.deletedCount != 1) { throw new errors.LeafnodeObjectSetDeleteError( 'deleteObject failed to delete the document', 1, result.deletedCount) } }, cb) } /*************************************************************************************************** * @method removeObject * @description Remove a single document. * @param {xxx} _id -- The _id of the doc to remove. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} * @deprecated Use {@link deleteObject} */ Collection.prototype.removeObject = function(_id, options, cb) { return this.deleteObject(_id, options, cb) } /*************************************************************************************************** * @method deleteObjects * @description Delete multiple documents. * @param {xxx} _ids -- The _ids of the docs to delete. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} */ Collection.prototype.deleteObjects = function(_ids, options, cb) { if (!_.isArray(_ids)) { _ids = [_ids] } if (_.some(_ids, function(_id) { return _.isNil(_id) })) { var err = new Error('_ids required') if (cb) { return cb(err) } throw err } var query = {_id: {'$in': _ids}} syncOrAsync(this._collection, 'deleteMany', [query, options], function(result) { if (result.deletedCount != _ids.length) { throw new errors.LeafnodeObjectSetDeleteError( 'deleteObjects failed to delete one or more documents', _ids.length, result.deletedCount) } }, cb) } /*************************************************************************************************** * Remove multiple documents. * @method removeObjects * @description Remove multiple documents. * @param {xxx} _ids -- The _ids of the docs to remove. * @param {object} [options=null] -- Optional settings. * @param {number|string} [options.w=null] -- The write concern. * @param {number} [options.wtimeout=null] -- The write concern timeout. * @param {boolean} [options.j=false] -- Specify a journal write concern. * @param {function} [cb=undefined] -- execute asynchronously if present (signature: cb(err, result)) * @throws {Error|LeafnodeObjectSetOperationError} * @deprecated Use {@link deleteObjects}. */ Collection.prototype.removeObjects = function(_ids, options, cb) { return this.deleteObjects(_ids, options, cb) } // XXX: for backward compatibility Collection.Collection = Collection module.exports = Collection