【问题标题】:Unable to Append Array Within MongoDB (mongoose) Document无法在 MongoDB(猫鼬)文档中追加数组
【发布时间】:2020-12-04 12:26:14
【问题描述】:

我正在尝试使用在前端(网站 ui)中创建的字符串在 mongo 数据库中附加一个空数组,相关代码片段如下:

猫鼬模式

    email: String,
    displayName: String,
    googleId: String,
    toIgnore: [{toIgnoreURL: String}]
})

使用护照和护照-google-oauth20 创建文档

User.findOne({email: email.emails[0].value}).then((currentUser)=>{
            if(currentUser){
                // user does already exist
                console.log('welcome back!', currentUser)
                done(null, currentUser)
            }
            else{ // user doesn't exist yet
            new User({
                email: email.emails[0].value,
                displayName: email.displayName,
                googleId: email.id,
                toIgnore: []
            }).save().then((newUser)=>{
                console.log('new user created: ' + newUser)
                done(null, newUser)
            });
            }
        })

最后尝试附加“用户”集合(当前登录用户的)的 toIgnore 数组属性

User.update(
        {email: emailThisSession},
        {$push: {toIgnore: {toIgnoreURL: url}}})

在mongodb中我看到下面的文档创建成功了

_id
:ObjectId(
IdOfDocumentInMongoDB)
toIgnore
:
Array
email
:
"myactualtestemail"
googleId
:
"longgoogleidonlynumbers"
__v
:
0

(也见附图) document in mongodb ui

我似乎不知道如何实际填充“toIgnore”数组。 例如,当控制台记录以下内容时

var ignoreList = User.findOne({email:emailThisSession}).toIgnore;
console.log(ignoreList)

输出为undefined 请注意,控制台记录 url 变量确实会打印我想要附加到数组的值! 我尝试了在模式构建器和文档创建中我能想到的任何格式组合,但我找不到正确的方法来完成它! 任何帮助将不胜感激!

更新,使用 promise 也不起作用

User.findOne({email:emailThisSession}).then((currentUser)=>{ //adding .exec() after findOne({query}) does not help as in User.findOne({email:emailThisSession}).exec().then(...)
            console.log(currentUser.toIgnore, url) //output is empty array and proper value for url variable, empty array meaning []
            currentUser.toIgnore.push(url)
        });

同时调整Schema如下:

const userSchema = new Schema({
    email: String,
    displayName: String,
    googleId: String,
    toIgnore: []
})

解决方案

我只需要将更新命令更改为

User.updateOne(
            {email: emailThisSession},
            {$push: {toIgnore: {toIgnoreURL: url}}}).then((user)=>{
                console.log(user)
            })

谢谢@yaya!

【问题讨论】:

    标签: node.js arrays mongodb mongoose passport.js


    【解决方案1】:

    无法使用 mongoose 在文档中添加数组元素

    1. 将您的架构定义为:
    const UserSchema = new mongoose.Schema({
      ...
      toIgnore: [{toIgnoreURL: String}]
    })
    
    1. 那么您可以像这样创建一个对象:
    new User({
      ...,
      toIgnore: [] // <-- optional, you can remove it
    })
    
    1. 检查值:
    User.findOne({...}).then(user => {
      console.log(user.toIgnore)
    });
    
    1. 您的更新声明应为:
    User.update(
      {email: emailThisSession},
      {$push: {toIgnore: {toIgnoreURL: url}}}
    ).then(user => {
      console.log(user)
    })
    

    所以在你的情况下,这是未定义的:

    User.findOne({email:emailThisSession}).toIgnore
    

    因为findOne 是异步的。要获得结果,您可以将其传递给回调,也可以使用 Promise (User.findOne({...}).then(user =&gt; console.log(user.toIgnore)))

    更新:

    同时调整Schema如下:new Schema({..., toIgnore: []})

    这是您的更新的问题。你应该把它改回:toIgnore: [{toIgnoreURL: String}]

    【讨论】:

    • @Hope2Code 您的更新有问题。更新了答案。
    • 我确实设法打印了一个空数组,如代码 var ignoreList = User.findOne({email:emailThisSession}).then((currentUser)=&gt;{ console.log(currentUser.toIgnore, url) currentUser.toIgnore.push(url) }); 的忽略列表中一样,但我仍然无法使用 .push 附加数组
    • @Hope2Code 查看更新。您的架构不正确,因此它不会保存更新的值。首先更正您的架构,然后再次调用update user 让它再次保存更新的值。
    • @Hope2Code 现在我可以看到另一个问题。 User.update(...) 没有被执行,你应该手动执行它。例如:User.update(...).then(user =&gt; {console.log(user)}).exec()
    • @Hope2Code 架构是正确的。但 updateOne 不是。then 表示 execute the statement and get the result.。所以应该是:User.updateOne( {email: emailThisSession}, {$push: {toIgnore: {toIgnoreURL: url}}}).then((user)=&gt;{console.log('done', user)})
    猜你喜欢
    • 2017-02-25
    • 2016-07-30
    • 2014-11-07
    • 2017-06-01
    • 2019-03-04
    • 2013-09-15
    • 2019-08-09
    • 2021-06-30
    • 2017-07-05
    相关资源
    最近更新 更多