Mongoose在一个查询中更新或创建许多值

时间:2015-12-02 12:18:26

标签: node.js mongodb mongoose

我有这样的文件:

{
    "_id" : ObjectId("565e906bc2209d91c4357b59"),
    "userEmail" : "abc@example.com",
    "subscription" : {
        "project1" : {
            "subscribed" : false
        },
        "project2" : {
            "subscribed" : true
        },
        "project3" : {
            "subscribed" : false
        },
        "project4" : {
            "subscribed" : false
        }
    }
}

我使用快递来发布我的帖子后服务电话:

router.post('/subscribe', function(req, res, next) {
    MyModel.findOneAndUpdate(
        {
            userEmail: req.body.userEmail
        },
        {
            // stuck here on update query
        },
        {
            upsert: true
        }, function(err, raw) {
            if (err) return handleError(err);
            res.json({result: raw});
        }
    )
});

我的req包含以下数据:

{
    userEmail: "abc@example.com",
    subscription: ["project1", "project4"]
}

所以这些是我想在此次通话中执行的步骤:

  1. 检查用户是否存在,否则创建用户。例如,如果abc@example.com不存在,请使用userEmail创建一个新文档abc@example.com

  2. 如果用户存在,请检查project1对象中是否存在project4subscription。如果没有创建那些。

  3. 如果project1中存在project4subscription,请将subscribed更新为true

  4. 我不确定我是否可以通过一次查询完成上述所有3个步骤。请建议。

1 个答案:

答案 0 :(得分:0)

Vimalraj,

您可以使用$set完成此操作。 $set运算符用指定的值替换字段的值。根据文件:

  

如果该字段不存在,$set将添加具有指定值的新字段,前提是新字段不违反类型约束。如果为不存在的字段指定虚线路径,$ set将根据需要创建嵌入文档,以实现该字段的虚线路径。

由于您的req.subscription将是一个数组,因此您必须构建查询。看起来像这样:

{ 
  $set: { 
    "subscription.project1":{"subscribed" : true},
    "subscription.project4":{"subscribed" : true}
}

您可以使用reducereq.subscription = ["project1","project4"] array

创建对象
var subscription= req.subscription.reduce(function(o,v){
  o["subscription." + v] = {subscription:true};
  return o;
},{});

然后您的代码变为:

router.post('/subscribe', function(req, res, next) {

    var subscription= req.subscription.reduce(function(o,v){
      o["subscription." + v] = {subscription:true};
      return o;
    },{});

    MyModel.findOneAndUpdate(
        {
            userEmail: req.body.userEmail
        },
        {
             $set: subscription
        },
        {
            upsert: true
        }, function(err, raw) {
            if (err) return handleError(err);
            res.json({result: raw});
        }
    )
});