在mongoose中更新模式以添加新属性

Win*_*cca 7 mongoose mongodb node.js mongoose-schema

我正在尝试更新架构以添加新的属性字段.我希望它可以像将属性添加到模式一样简单,并且可以访问更新的字段.

我有一个现有的架构

  let userDrinkSchema = new mongoose.Schema({  new Schema
    creator : { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'user'  // name of user file
    },
    caffeine: Number,
    mgFloz: Number,
    name: String,
    size: Number,
    updated_at: {
        type: Date,
        default: Date.now()
    }
});
Run Code Online (Sandbox Code Playgroud)

我需要从这个架构中添加id

const UserSchema = mongoose.Schema({

const User = module.exports = mongoose.model('User', UserSchema);
Run Code Online (Sandbox Code Playgroud)

我不知道如何为每个用户添加此属性.我按照这个例子 处理了Mongoose中的模式更改

架构现在是:

let DrinkSchema = new mongoose.Schema({
    user: { 
        type: mongoose.Schema.Types.ObjectId, 
        ref: 'user',
        required: true,
        default: null
    },
    caffeine: Number,
    mgFloz: Number,
    name: String,
    size: Number,
    imageUrl: String,
    date: {
        type: Date,
        default: Date.now()
    }
},
{
    collection: 'drinkList'
});
Run Code Online (Sandbox Code Playgroud)

不幸的是,用户也是空的

{
 "_id":"58bba13bb7afeaa3180aa929",
 "caffeine":422,"mgFloz":218.7,
 "name":"10 Hour Energy Shot",
 "size":1.93,
 "url":"/caffeine-content/10-hour-eternal-shot",
 "date":"2017-03-28T13:10:12.650Z",
 "user":null
}
Run Code Online (Sandbox Code Playgroud)

有没有办法更新用户字段以获取用户信息?我引用的架构设置为

const SelectedDrinks = require('./userDrinks').schema;
const UserSchema = mongoose.Schema({
    name: {
        type: String
    },
    email: {
        type: String,
        required: true
    },
    username: {
        type: String, 
        required: true
    },
    password: {
        type: String,
        required: true
    },
    caffeine_list: [SelectedDrinks]
})
Run Code Online (Sandbox Code Playgroud)

我可以看到mongodb在创建时为每个用户添加了一个id.这就是我想要访问的内容.

我的后端路由是在express中配置的.随着邮递员,我可以得到这个工作,因为我有用户ID.我不知道如何在此路由中获取正确的用户ID.

    router.post('/addDrink', (req, res, next) => {
    let newDrink = new UserDrinks({
        creator: req.body.creator, // need id get user object id()
        caffeine: req.body.caffeine,
        mgFloz: req.body.mgFloz,
        name: req.body.name,
        size: req.body.size,
        updated_at: req.body.updated_at
    });

    newDrink.save( (err) => {
        if(err) {
            res.send(err);
        } else {
            User.findOne({ _id: newDrink.creator},  (err, user) => {
                user.caffeine_list.addToSet(newDrink)
                user.save( function (err) {
                    if(err) {
                        console.log(err);
                    }else {
                        res.status(201).json(newDrink);
                    }
                })
            })

        }

    })
});
Run Code Online (Sandbox Code Playgroud)

Kev*_*ern 5

如果我了解此权利,则您正在尝试将该creator字段替换为该user字段。为此,您需要做两件事:

  1. 修改/addDrink路线
  2. 更新drinkList集合中的所有现有文档

1)创建时newDrink,请设置,user而不是creator

let newDrink = new UserDrinks({
    user: req.body.creator,
    caffeine: req.body.caffeine,
    mgFloz: req.body.mgFloz,
    name: req.body.name,
    size: req.body.size,
    updated_at: req.body.updated_at
});
Run Code Online (Sandbox Code Playgroud)

2)更新全部UserDrinks以重命名该字段:

UserDrinks.update({}, { $rename: { "creator" : "user" } }, { multi: true }, callback)
Run Code Online (Sandbox Code Playgroud)

这将找到所有UserDrinks文档,并将creator属性重命名为user

快速执行此操作而无需为一次性更改创建新路由的方法是在您的快速设置下为其创建一个临时功能,在本地运行它,然后删除/注释代码,以使其不再运行。例如:

function renameCreatorField() {
    UserDrinks.update({}, { $rename: { "creator" : "user" } }, { multi: true }, function(err, data) {
        if (!err) { 
            //success 
        }
    })
}

renameCreatorField();
Run Code Online (Sandbox Code Playgroud)

这将在服务器启动时立即运行。一旦运行,您就可以删除它,因为我们在(1)中所做的更改将确保以后的任何UserDrinks文档都具有正确的字段集。

当然,如果您只是在寻找快速解决方案,而这又不是实时应用程序,则可以执行(1),清除数据库并以正确的文档重新开始。但这不是学习的方式。:)