diff --git a/docs/api.jade b/docs/api.jade
index 6c40910e1d2..8813a06aeee 100644
--- a/docs/api.jade
+++ b/docs/api.jade
@@ -58,6 +58,10 @@ block content
h5 Returns:
ul
li «#{prop.return.types}» !{prop.return.description}
+ if prop.type != null
+ h5 Type:
+ ul
+ li «#{prop.type}»
div
| !{prop.description}
diff --git a/docs/middleware.jade b/docs/middleware.jade
index cdb27ececd1..a49dbd0316e 100644
--- a/docs/middleware.jade
+++ b/docs/middleware.jade
@@ -35,6 +35,8 @@ block content
In query middleware functions, `this` refers to the query.
* [count](./api.html#query_Query-count)
+ * [deleteMany](./api.html#query_Query-deleteMany)
+ * [deleteOne](./api.html#query_Query-deleteOne)
* [find](./api.html#query_Query-find)
* [findOne](./api.html#query_Query-findOne)
* [findOneAndDelete](./api.html#query_Query-findOneAndDelete)
diff --git a/docs/source/api.js b/docs/source/api.js
index f6db2f8b6f2..0c56d47d4e7 100644
--- a/docs/source/api.js
+++ b/docs/source/api.js
@@ -70,7 +70,13 @@ function parse() {
break;
case 'property':
ctx.type = 'property';
- ctx.name = tag.string;
+ let str = tag.string;
+ const match = str.match(/^{\w+}/);
+ if (match != null) {
+ ctx.type = match[0].substring(1, match[0].length - 1);
+ str = str.replace(/^{\w+}\s*/, '');
+ }
+ ctx.name = str;
ctx.string = `${ctx.constructor}.prototype.${ctx.name}`;
break;
case 'static':
diff --git a/lib/index.js b/lib/index.js
index cb0deb321c1..5ceaf557ed3 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -586,7 +586,7 @@ Mongoose.prototype.plugin = function(fn, opts) {
};
/**
- * The default connection of the mongoose module.
+ * The Mongoose module's default connection. Equivalent to `mongoose.connections][0]`, see [`connections`](#mongoose_Mongoose-connections).
*
* ####Example:
*
@@ -596,10 +596,11 @@ Mongoose.prototype.plugin = function(fn, opts) {
*
* This is the connection used by default for every model created using [mongoose.model](#index_Mongoose-model).
*
+ * To create a new connection, use [`createConnection()`](#mongoose_Mongoose-createConnection).
+ *
* @memberOf Mongoose
* @instance
- * @property connection
- * @return {Connection}
+ * @property {Connection} connection
* @api public
*/
@@ -614,6 +615,29 @@ Mongoose.prototype.__defineSetter__('connection', function(v) {
}
});
+/**
+ * An array containing all [connections](connections.html) associated with this
+ * Mongoose instance. By default, there is 1 connection. Calling
+ * [`createConnection()`](#mongoose_Mongoose-createConnection) adds a connection
+ * to this array.
+ *
+ * ####Example:
+ *
+ * const mongoose = require('mongoose');
+ * mongoose.connections.length; // 1, just the default connection
+ * mongoose.connections[0] === mongoose.connection; // true
+ *
+ * mongoose.createConnection('mongodb://localhost:27017/test');
+ * mongoose.connections.length; // 2
+ *
+ * @memberOf Mongoose
+ * @instance
+ * @property {Array} connections
+ * @api public
+ */
+
+Mongoose.prototype.connections;
+
/*!
* Driver dependent APIs
*/
diff --git a/lib/model.js b/lib/model.js
index 75f0fee692c..c4c59f0b3c6 100644
--- a/lib/model.js
+++ b/lib/model.js
@@ -427,6 +427,7 @@ function generateVersionError(doc, modifiedPaths) {
* @param {Boolean} [options.j] set to true for MongoDB to wait until this `save()` has been [journaled before resolving the returned promise](https://docs.mongodb.com/manual/reference/write-concern/#j-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
* @param {Number} [options.wtimeout] sets a [timeout for the write concern](https://docs.mongodb.com/manual/reference/write-concern/#wtimeout). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern).
* @param {Boolean} [options.checkKeys=true] the MongoDB driver prevents you from saving keys that start with '$' or contain '.' by default. Set this option to `false` to skip that check. See [restrictions on field names](https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names)
+ * @param {Boolean} [options.timestamps=true] if `false` and [timestamps](./guide.html#timestamps) are enabled, skip timestamps for this `save()`.
* @param {Function} [fn] optional callback
* @return {Promise|undefined} Returns undefined if used with callback or a Promise otherwise.
* @api public
@@ -465,8 +466,11 @@ Model.prototype.save = function(options, fn) {
return cb(parallelSave);
}
+ this.$__.saveOptions = options;
+
this.$__save(options, error => {
this.$__.saving = undefined;
+ delete this.$__.saveOptions;
if (error) {
this.$__handleReject(error);
diff --git a/lib/schema.js b/lib/schema.js
index 4adc3cd9eec..7cfae3207d5 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -918,6 +918,10 @@ Schema.prototype.setupTimestamp = function(timestamps) {
this.add(schemaAdditions);
this.pre('save', function(next) {
+ if (get(this, '$__.saveOptions.timestamps') === false) {
+ return next();
+ }
+
const defaultTimestamp = (this.ownerDocument ? this.ownerDocument() : this).
constructor.base.now();
const auto_id = this._id && this._id.auto;
diff --git a/test/schema.timestamps.test.js b/test/schema.timestamps.test.js
index e6ff61287f4..5c934bb5ee8 100644
--- a/test/schema.timestamps.test.js
+++ b/test/schema.timestamps.test.js
@@ -222,6 +222,22 @@ describe('schema options.timestamps', function() {
});
});
+ it('can skip with timestamps: false (gh-7357)', function() {
+ return co(function*() {
+ const cat = yield Cat.findOne();
+
+ const old = cat.updatedAt;
+
+ yield cb => setTimeout(() => cb(), 10);
+
+ cat.hobby = 'fishing';
+
+ yield cat.save({ timestamps: false });
+
+ assert.strictEqual(cat.updatedAt, old);
+ });
+ });
+
it('should change updatedAt when findOneAndUpdate', function(done) {
Cat.create({name: 'test123'}, function(err) {
assert.ifError(err);