如何通过一次调用将一组对象推送到猫鼬中的数组中?

Posted

技术标签:

【中文标题】如何通过一次调用将一组对象推送到猫鼬中的数组中?【英文标题】: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] 

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

【问题讨论】:

【参考方案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 以插入。

【讨论】:

以上是关于如何通过一次调用将一组对象推送到猫鼬中的数组中?的主要内容,如果未能解决你的问题,请参考以下文章

如何推送到猫鼬中的数组

如何让猫鼬将一组 url 推送到数组子文档

将元素推送到猫鼬中的数组

如何仅通过一次调用将一组对象保存到猫鼬数据库?

如何在猫鼬中动态地将值推入对象的属性?

如何避免在对象内部创建对象并使用猫鼬将元素直接推送到快速数组中?