我是否需要在Mongoose模式中列出派生属性?

时间:2015-07-31 17:25:04

标签: mongoose

我是否需要列出Mongoose架构中的派生属性?这是架构最佳实践吗?

我使用.post('init')挂钩从保存的值派生属性。例如,我连接fnamelname以在post init钩子中间件中创建fullName

但是这个中间件不起作用:

ContactSchema = new new mongoose.Schema({
  fname: String,
  lname: String 
});

ContactSchema.post('init',function(doc){
  doc.fullName= 'fname` + ' ' + 'lname';
});

// ... declare model

ContactModel.findOne({_id: req.params.contactId}).then(function(result){
  console.log(result);
  // {fname: "John",
  //  lname: "Smith"}
  //
  //  missing fullName!
});

除非我将架构更改为列出fullName,否则它可以工作,并且在中间件内部fineOne()之后设置fullName属性。

ContactSchema = new new mongoose.Schema({
  fname: String,
  lname: String,
  fullName: String,
});

ContactSchema.post('init',function(doc){
  doc.fullName= 'fname` + ' ' + 'lname';
});

// ... declare model

ContactModel.findOne({_id: req.params.contactId}).then(function(result){
  console.log(result);
  // {fname: "John",
  //  lname: "Smith",
  //  fullName: "John Smith"}
  //
  //  now fullName is populated and middleware works!
});

我是否应该列出永远不会保存的属性,以便我可以使我的中间件工作?这是最佳做法吗?

1 个答案:

答案 0 :(得分:2)

I think you want to use virtuals instead.

For example:

var mongoose = require('mongoose');

// Create the schema.
var ContactSchema = new mongoose.Schema({
  fname: String,
  lname: String 
});

// Create a virtual property called `fullName`.
ContactSchema.virtual('fullName').get(function() {
  return this.fname + ' ' + this.lname;
});

// Create the model.
var Contact = mongoose.model('Contact', ContactSchema);

// Instantiate a contact.
var contact = new Contact({ fname : 'John', lname : 'Doe' });

// Print their full name.
console.log(contact.fullName);

Combined with a query, it's basically the same:

contact.save(function(err) {
  if (err) throw err;
  Contact.findOne({}, function(err, contact) {
    if (err) throw err;
    console.log(contact.fullName);
  });
});

The only caveat is that when you want to convert your document to a plain JS object (for instance, if you want to subsequently convert that to a JSON string), you have to tell Mongoose to also include virtuals:

// Log the entire document as JSON:
console.log('%j', contact.toObject({ virtuals : true }));