默认值

¥Defaults

在你的结构中声明默认值

¥Declaring Defaults in Your Schema

你的结构可以定义某些路径的默认值。如果你在没有设置该路径的情况下创建新文档,则将启动默认路径。

¥Your schemas can define default values for certain paths. If you create a new document without that path set, the default will kick in.

注意:仅当路径值严格为 undefined 时,Mongoose 才会应用默认值。

¥Note: Mongoose only applies a default if the value of the path is strictly undefined.

const schema = new Schema({
  name: String,
  role: { type: String, default: 'guitarist' }
});

const Person = db.model('Person', schema);

const axl = new Person({ name: 'Axl Rose', role: 'singer' });
assert.equal(axl.role, 'singer');

const slash = new Person({ name: 'Slash' });
assert.equal(slash.role, 'guitarist');

const izzy = new Person({ name: 'Izzy', role: undefined });
assert.equal(izzy.role, 'guitarist');

// Defaults do **not** run on `null`, `''`, or value other than `undefined`.
const foo = new Person({ name: 'Bar', role: null });
assert.strictEqual(foo.role, null);

await Person.create(axl, slash);

const docs = await Person.find({ role: 'guitarist' });

assert.equal(docs.length, 1);
assert.equal(docs[0].name, 'Slash');

默认功能

¥Default Functions

你还可以将 default 结构选项设置为函数。Mongoose 将执行该函数并使用返回值作为默认值。

¥You can also set the default schema option to a function. Mongoose will execute that function and use the return value as the default.

const schema = new Schema({
  title: String,
  date: {
    type: Date,
    // `Date.now()` returns the current unix timestamp as a number
    default: Date.now
  }
});

const BlogPost = db.model('BlogPost', schema);

const post = new BlogPost({ title: '5 Best Arnold Schwarzenegger Movies' });

// The post has a default Date set to now
assert.ok(post.date.getTime() >= Date.now() - 1000);
assert.ok(post.date.getTime() <= Date.now());

setDefaultsOnInsert 选项

¥The setDefaultsOnInsert Option

当通过将结构的默认值添加到 MongoDB $setOnInsert 运算符 来设置 upsert 选项时,Mongoose 还会在 update()findOneAndUpdate() 上设置默认值。你可以通过将 setDefaultsOnInsert 选项设置为 false 来禁用此行为。

¥Mongoose also sets defaults on update() and findOneAndUpdate() when the upsert option is set by adding your schema's defaults to a MongoDB $setOnInsert operator. You can disable this behavior by setting the setDefaultsOnInsert option to false.

const schema = new Schema({
  title: String,
  genre: { type: String, default: 'Action' }
});

const Movie = db.model('Movie', schema);

const query = {};
const update = { title: 'The Terminator' };
const options = {
  // Return the document after updates are applied
  new: true,
  // Create a document if one isn't found.
  upsert: true
};

let doc = await Movie.findOneAndUpdate(query, update, options).lean();
doc.genre; // 'Action', Mongoose set a default value.

await Movie.deleteMany({});

doc = await Movie.findOneAndUpdate(query, update, { new: true, upsert: true, setDefaultsOnInsert: false }).lean();
doc.genre; // undefined, Mongoose did not set a default value

你还可以全局设置 setDefaultsOnInsertfalse

¥You can also set setDefaultsOnInsert to false globally:

mongoose.set('setDefaultsOnInsert', false);

默认功能和 this

¥Default functions and this

除非它在带有 setDefaultsOnInsert 的查询上运行,否则默认函数的 this 引用文档。

¥Unless it is running on a query with setDefaultsOnInsert, a default function's this refers to the document.

const schema = new Schema({
  title: String,
  released: Boolean,
  releaseDate: {
    type: Date,
    default: function() {
      if (this.released) {
        return Date.now();
      }
      return null;
    }
  }
});

const Movie = db.model('Movie', schema);

const movie1 = new Movie({ title: 'The Terminator', released: true });

// The post has a default Date set to now
assert.ok(movie1.releaseDate.getTime() >= Date.now() - 1000);
assert.ok(movie1.releaseDate.getTime() <= Date.now());

const movie2 = new Movie({ title: 'The Legend of Conan', released: false });

// Since `released` is false, the default function will return null
assert.strictEqual(movie2.releaseDate, null);