【问题标题】:How to push an array of objects into an array in mongoose with one call?如何通过一次调用将一组对象推送到猫鼬中的数组中?
【发布时间】:2012-08-11 09:59:56
【问题描述】:

我需要使用一次调用将多个值推送到 mongoose 中的数组中。我尝试使用较小的数组来执行此操作,但该数组被作为子数组插入。

var kittySchema = new mongoose.Schema({
        name: String,
        values: [Number]
});

var Kitten = db.model('Kitten', kittySchema);
Kitten.update({name: 'fluffy'},{$push: {values:[2,3]}},{upsert:true},function(err){
        if(err){
                console.log(err);
        }else{
                console.log("Successfully added");
        }
});

上述代码三次调用的结果如下:

{ "_id" : ObjectId("502b0e807809d79e84403606"), "name" : "fluffy", "values" : [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ] }

而我想要的是这样的:

{ "_id" : ObjectId("502b0e807809d79e84403606"), "name" : "fluffy", "values" : [ 2, 3 ,2 ,3, 2, 3] }

我注意到的另一件事是数组(值)中的类型被指定为数字,那么“严格”选项不会确保不插入除数字之外的任何内容吗?在这种情况下,允许插入另一个数组。

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    (2014 年 12 月更新) 从 MongoDB2.4 开始,您应该使用:

    Kitten.update({name: 'fluffy'}, {$push: {values: {$each: [2,3]}}}, {upsert:true}, function(err){
            if(err){
                    console.log(err);
            }else{
                    console.log("Successfully added");
            }
    });
    

    【讨论】:

    • 如果不存在带有{name: "fluffy"} 的文档,{upsert: true} 会创建它吗?另外,如果我执行{upsert: true, new: true},我可以执行 function(err, result) {} 并获取所有已创建/更新的文档吗?
    【解决方案2】:

    已弃用请参阅下面使用 $push $each 的其他解决方案

    您的示例很接近,但您希望 $pushAll 而不是 $push 分别添加每个值(而不是将另一个数组推入 values 数组):

    var Kitten = db.model('Kitten', kittySchema);
    Kitten.update({name: 'fluffy'},{$pushAll: {values:[2,3]}},{upsert:true},function(err){
            if(err){
                    console.log(err);
            }else{
                    console.log("Successfully added");
            }
    });
    

    【讨论】:

    • 注意:您可能还想查看$addToSet,它可用于仅将值添加到数组中(如果它们不存在)。
    • 谢谢斯坦尼!这样可行。我错过了文档中的这一部分。
    • @Stennie 这仅适用于单个元素,不适用于连接数组。
    • @Tom 连接数组可以使用 $addToSet 和 $each 来完成。
    【解决方案3】:

    或者将 $each 修饰符与 $addToSet 一起使用:

    https://docs.mongodb.com/manual/reference/operator/update/addToSet/#each-modifier

    // Existing tags array
    { _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }
    
    // Add "camera" and "accessories" to it
    db.inventory.update(
       { _id: 2 },
       { $addToSet: { tags: { $each: [ "camera", "accessories" ] } } }
     )
    

    【讨论】:

      【解决方案4】:

      目前,更新后的doc 不支持$pushAll。它似乎已被弃用。 现在比较好的选择是使用$push & $each的组合

      一个例子:

      //User schema: {uid: String, transaction: [objects] }
      const filter = {"uid": uid};
      const update = {
              $push: {
                  transactions: {$each: dataarr}
              }
          }
      User.updateOne(filter, update, {upsert:true}, (err) => {
              if(err){
                  console.log(err)
              }
          })
      

      如果过滤器返回 false,则在选项中传递 {upsert: true} 以插入。

      【讨论】:

        猜你喜欢
        • 2012-04-16
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        • 2021-02-09
        • 2020-03-17
        • 2019-03-22
        • 1970-01-01
        相关资源
        最近更新 更多