mongodb更新推送阵列

时间:2014-06-07 05:46:19

标签: node.js mongodb sails.js

我有以下架构。我正在使用node.js和mongodb

attributes: {
    type: { type: 'string' },
    title: { type:'string' },
    description: { type:'string' },
    is_active: { type:'boolean',defaultsTo:true },
    createdBy: { type:'json' },
    attachments:{ type:'array' }
}

arr = [{
    'id':attResult.id,
    'subtype':type,
    'title'  : attResult.title,
    'body'  : attResult.body,
    'filetype' : attResult.filetype
}];

我正在尝试将附件添加到附件中#39;对文档来说唯一的数组。

这是我的疑问。

books.update(
    { id: refid },
    { $push: { attachments: arr } }
).done(function (err, updElem) {
    console.log("updElem" + JSON.stringify(updElem));     
});

我的查询有什么问题,没有错误,但没有更新附件。

我希望我的结果是:

{ 
    "_id" : 5,
    "attachments": [
        { 
            "id": "xxxxxxx",
            "subtype": "book",
            "title": "xxxx",
            "body": "xxxx" ,
            "filetype" : "xxxxx"
        },
        {
            "id": "xxxxxxx",
            "subtype": "book",
            "title": "xxxx",
            "body": "xxxx",
            "filetype": "xxxxx"
        }
    ]
}

3 个答案:

答案 0 :(得分:1)

再多看看你的问题,我打赌你实际上正在使用" sails"即使你的问题没有被标记,也在这里。

这里的问题是,水线ODM / ORM有自己的想法,关于实际支持哪种操作,因为它试图在使用SQL / NoSQL后端和某些可能的需求之间不可知。做事。

结果是目前不支持$push的更新,您需要更多的JavaScript操作事项。所以实际上你需要通过.findOne.save()操作来操纵它:

books.findOne(refid).exec(function(err,book) {
   book.attachments.push( arr[0] );
   book.save(function(err){
     // something here
   });
});

部分原因是"水线"以_idid作为术语的可互换使用的简写,其中仅将id值指定为单个参数意味着您指的是{{1}您的查询选择中的值。

因此,除非你更换水线ODM / ORM,否则你几乎坚持使用这个AFAIK,直到决定以一种与MongoDB API更加一致的方式维护这个逻辑,或者允许访问"生"用于执行这些id操作的驱动程序接口。

作为参考,但已被提及,你的将军" shell"语法或MongoDB特定驱动程序支持的内容与$pushAll运算符的弃用相同,并且意图使用{$push$addToSet运算符合并功能{3}}修饰符:

.update()

因此语法适用于适用的地方,但是对于你我认为在#34; sails"它不会。

这给了你一些思考的东西,以及对正确做事方式的一些见解。

答案 1 :(得分:1)

现在可以使用本机mongodb库尝试将元素推入数组的人。

考虑以下mongodb集合对象

{ 
"_id" : 5,
"attachments": [
    { 
        "id": "xxxxxxx",
        "subtype": "book",
        "title": "xxxx",
        "body": "xxxx" ,
        "filetype" : "xxxxx"
    },
    {
        "id": "xxxxxxx",
        "subtype": "book",
        "title": "xxxx",
        "body": "xxxx",
        "filetype": "xxxxx"
    }
]
}


 arr = [{
 'id':'123456',
 'subtype':'book',
 'title'  : 'c programing',
 'body'  :' complete tutorial for c',
 'filetype' : '.pdf'
 },
{
 'id':'123457',
 'subtype':'book',
 'title'  : 'Java programing',
 'body'  :' complete tutorial for Java',
 'filetype' : '.pdf'
 }
];

以下查询可用于将数组元素最后推送到“附件”。 $ push或$ addToSet可以用于此目的。

这将在附件中插入一个对象或元素

db.collection('books').updateOne(
  { "_id": refid }, // query matching , refId should be "ObjectId" type
  { $push: { "attachments": arr[0] } } //single object will be pushed to attachemnts
 ).done(function (err, updElem) {
  console.log("updElem" + JSON.stringify(updElem));     
});

这会将数组中的每个对象插入附件中

   db.collection('books').updateOne(
     { "_id": refid }, // query matching , refId should be "ObjectId" type
     { $push: { "attachments":{$each: arr} } } // arr will be array of objects
     ).done(function (err, updElem) {
           console.log("updElem" + JSON.stringify(updElem));     
    });

答案 2 :(得分:0)

您正在尝试将array作为元素插入到数组中。您可能希望将$pushAll视为短期解决方案。不推荐使用此运算符see here

或者你可以简单地迭代你的数组,每次迭代都会将你的数组中的一个元素推送到attachments(这是Mongo开发人员推荐的方法)。