【问题标题】:Do I need to list derived properties in Mongoose schema?我需要在 Mongoose 模式中列出派生属性吗?
【发布时间】:2015-08-01 13:56:31
【问题描述】:

我是否需要在 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,否则它可以工作,并且 fullName 属性设置在中间件内的 fineOne() 之后。

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!
});

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

【问题讨论】:

    标签: mongoose


    【解决方案1】:

    我想你想改用virtuals

    例如:

    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);
    

    结合查询,基本一样:

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

    唯一需要注意的是,当您想将文档转换为纯 JS 对象时(例如,如果您想随后将其转换为 JSON 字符串),您必须告诉 Mongoose 也包含虚拟对象:

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

    【讨论】:

    • 但是我在某个地方读到了我们无法查询虚拟的地方。这是真的吗?
    • 我的用例是查询,如果我使用 toJSON,虚拟机可以工作,但使用 toObject 时,虚拟机在查询后似乎不起作用。
    • @steampowered virtuals 也应该在查询后工作,请参阅我的编辑。你仍然必须使用{ virtuals : true }toObject()toJSON())。
    • @Vimal 没错,您无法查询虚拟对象,因为它们没有保存到数据库中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2020-12-02
    相关资源
    最近更新 更多