MongoDB + Mongoose:仅当给定密钥不存在或具有假值时才设置$

时间:2016-04-08 21:04:18

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

我需要有关findOneAndUpdate({upsert:true})查询的帮助:

得到了这个shchema:

    usersSchema = new Schema(
    {
        name: {type: String, unique: true, uniqueCaseInsensitive: true},    // username
        password: {type: String, minlength: 4},
        slug: {type: String, unique: true, uniqueCaseInsensitive: true},    // ok - Automatic on backend - based on name
        firstName: {type: String},
        middleName: {type: String},
        lastName: {type: String},
        email: {type: String, unique: true, uniqueCaseInsensitive: true},
        //country: {type: String, required: true, minlength: 3}
        socialIDs: {
            facebook: {
                id: {type: String, unique: true}
            },
            twitter: {},
            google: {}
        }
    }

当用户是新的,使用facebook(使用passportjs)创建帐户时,firstName,lastName,email等的数据将填充facebook检索的数据。如果用户通过本地策略创建了他的帐户,那些字段可能不存在,并且他第一次登录Facebook时,他们已经填充(更新个人资料)。

完美。

现在说,用户通过在线表格手动更新他的个人资料,在第一次登录Facebook之前,并设置一个电子邮件地址(与他的Facebook帐户相关联)。

当他用他的Facebook登录时,电子邮件地址将被从他的Facebook帐户中检索到的电子邮件地址覆盖。

有没有办法将findOneAndUpdate()方法设置为仅插入不存在的键(或者可能是给定键默认值的值)?

也许以某种方式将$ set与$ exists运算符组合在一起(我试过这个,但是找不到正确的语法)

我正在使用的查询如下:

    User.findOneAndUpdate(
        {
            $or: [
                {email: profile._json.email},
                {socialIDs: {facebook: {id: profile._json.id}}}
            ]
        },
        {
            $set: {
                firstName: profile._json.first_name,
                middleName: profile._json.middle_name,
                lastName: profile._json.last_name,
                avatar: profile._json.picture,
                gender: profile._json.gender,
                email: profile._json.email,
                socialIDs: {
                    facebook: {
                        id: profile._json.id,
                        profileLink: profile._json.link,
                    }
                }
            }
        },
        {new: true, upsert: true},
        function(err, user){
            done(err, user)
        });

谢谢你们!

1 个答案:

答案 0 :(得分:0)

没有条件$set,但是,如果用户已经创建了一个帐户并且他 提供了他的电子邮件,那么登录Facebook就不应该& #39; t覆盖它,这意味着您可以从$set运算符中删除该电子邮件。

一旦你有了这个,你就会得到用户尚未注册(upsert)的用例,在这种情况下,你只能在那个场景中使用$setOnInsert设置电子邮件。