@carbon-io/leafnode
Version:
Sync driver for MongoDB
902 lines (841 loc) • 50 kB
JavaScript
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