【问题标题】:Cannot add property to mongoose document with findOneAndUpdate无法使用 findOneAndUpdate 向 mongoose 文档添加属性
【发布时间】:2021-06-22 23:12:55
【问题描述】:

我的express 应用尝试使用Mongoose's findOneAndUpdate 记录用户的登录时间。

router.post('/login', passport.authenticate('local', {
    failureFlash: true,
    failureRedirect: '/'
}), async(req, res, next) => {
    // if we're at this point in the code, the user has already logged in successfully.
    console.log("successful login")
    // save login time to database
    const result = await User.findOneAndUpdate({ username: req.body.username }, { loginTime: Date.now() }, { new: true });
    console.log(result);
    return res.redirect('/battle');
})

用户文档开始时没有登录时间属性。我期待这段代码为我插入该属性。

实际结果是,控制台显示正在打印的用户文档,但没有添加任何登录时间属性。我该如何解决这个问题,以便将登录时间属性插入到文档中?通过在原始猫鼬模式中定义登录时间属性是唯一的方法吗?如果是这样,这是否会抵消 NoSQLSQL 的所谓优势,因为它应该允许新的意外属性类型进入您的集合和文档?

【问题讨论】:

  • 您可以检查req.body.username 中的值是什么(这将验证是否存在相应的文档)。
  • 这不是问题。该文档已经存在,我可以在数据库中看到它,并且 console.log(result) 将完整的文档打印出来。问题是没有使用 findOneAndUpdate 将 loginTime 属性添加到文档中。
  • 检查程序是否连接到正确的数据库和集合?
  • 它连接到正确的数据库和集合。

标签: node.js mongodb express mongoose


【解决方案1】:

我已经为可能遇到相同问题的任何人找到了答案。如果尚未在 Schema 中定义属性,则根本不可能将属性添加到 Mongoose 集合。因此,为了修复它,我在 Schema 中添加了该属性。

【讨论】:

    【解决方案2】:

    事实上,您可以添加未在架构中定义的新属性,而无需修改架构。您需要将标志 strict 设置为 false 以启用此模式。参见文档here

    下面的代码演示了我所说的,随意运行它:

    const mongoose = require('mongoose');
    
    // connect to database
    mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false });
    
    // define the schema 
    const kittySchema = new mongoose.Schema({
        name: String
    
        // this flag indicate that the shema we defined is not fixed, 
        // document in database can have some fields that are not defined in the schema
        // which is very likely
    }, { strict: false });
    
    // compile schema to model
    const Kitten = mongoose.model('Kitten', kittySchema);
    
    test();
    async function test() {
    
        // empty the database
        await Kitten.deleteMany({});
    
        // test data
        const dataObject = { name: "Kitty 1" };
        const firstKitty = new Kitten(dataObject);
    
        // save in database
        await firstKitty.save();
    
        // find the kitty from database
        const firstKittyDocument = await Kitten.findOne({ name: "Kitty 1" });
        console.log("Mongoose document", firstKittyDocument);
    
        // modify the kitty, add new property doesn't exist in the schema
        const firstKittyDocumentModified = await Kitten.findOneAndUpdate(
            { _id: firstKittyDocument._id },
            { $set: { age: 1 } },
            { new: true }
        );
        console.log("Mongoose document updated", firstKittyDocumentModified);
    
        // note : when we log the attribute that isn't in the schema, it is undefined :)
        console.log("Age ", firstKittyDocumentModified.age); // undefined
        console.log("Name", firstKittyDocumentModified.name); // defined
    
        // for that, use .toObject() method to convert Mongoose document to javascript object
        const firstKittyPOJO = firstKittyDocumentModified.toObject();
        console.log("Age ", firstKittyPOJO.age); // defined
        console.log("Name", firstKittyPOJO.name); // defined
    
    }
    

    输出:

    Mongoose document { _id: 60d1fd0ac3b22b4e3c69d4f2, name: 'Kitty 1', __v: 0 }
    Mongoose document updated { _id: 60d1fd0ac3b22b4e3c69d4f2, name: 'Kitty 1', __v: 0, age: 1 }
    Age  undefined
    Name Kitty 1
    Age  1
    Name Kitty 1
    

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 2017-08-13
      • 2016-04-25
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 2012-01-27
      • 2022-01-22
      相关资源
      最近更新 更多