mongodb 更新推送数组

问题描述:

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

I have the following schema. I am using node.js with 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
}];

我正在尝试将附件推送到文档唯一的附件"数组中.

I am trying to push a attachments into the 'attachments' array that will be unique to the document.

这是我的查询.

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

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

What is the problem in my query,no error but not updated attachments.

我希望我的结果是这样的:

I want my result to be this:

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

多看你的问题我敢打赌你实际上在这里使用了sails",即使你的问题没有被标记为这样.

Looking at your question a little bit more I'm betting that you are actually using "sails" here even though your question is not tagged as such.

>

这里的问题是水线 ODM/ORM 对实际支持的操作类型有自己的想法,因为它试图在使用 SQL/NoSQL 后端和某种需求之间不可知.

The issue here is that the waterline ODM/ORM has it's own ideas about what sort of operations are actually supported since it tries to be agnostic between working with SQL/NoSQL backends and sort of demands a certain may of doing things.

结果是使用 $push 目前还没有真正被支持,你需要更多的 JavaScript 操作.所以实际上你需要通过 .findOne.save() 操作来操作它:

The result is that updates with $push are not really supported at present and you need more of a JavaScript manipulation affair. So in fact you need to manipulate this via a .findOne and .save() operation:

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

其中一部分是水线"简写,否则将被视为 _idid 作为术语的可互换使用,其中仅指定 id 值作为单个参数意味着您在查询选择中引用了 id 值.

Part of that is "waterline" shorthand for what would otherwise be considered an interchangeable use of _id and id as terms, where just specifying the id value as a single argument implies that you are referring to the id value in your query selection.

因此,除非您更换水线 ODM/ORM,否则您几乎无法使用此 AFAIK,直到决定以与 MongoDB API 更一致的方式维护此逻辑或以其他方式允许访问原始"驱动程序接口来执行这些 .update() 操作.

So unless you replace the waterline ODM/ORM you are pretty much stuck with this AFAIK until there is a decision to maintain this logic in a way that is more consistent with the MongoDB API or otherwise allow access to the "raw" driver interface to perform these .update() operations.

作为参考,并且已经被提及,您的一般shell"语法或 MongoDB 特定驱动程序支持的其他内容是这样的,但 $pushAll 运算符,目的是将功能与$push$addToSet 操作符使用 $each代码> 修饰符:

For reference though, and has been alluded to, your general "shell" syntax or what would otherwise be supported in MongoDB specific drivers is like this with the deprecation of the $pushAll operator and the intention being to merge the functionality with the $push and $addToSet operators using the $each modifier:

db.collection.update(
   { "_id": ObjectId(refid) },    // should be important to "cast"
   {
      "$push": {
          "attachments": {
              "$each": arr
          }
      }
   }
)

所以这种语法在它适用的地方会起作用,但对你来说,我认为在sails"中它不会.

So that syntax would work where it applies, but for you I am thinking that in "sails" it will not.

这让您深思熟虑,并深入了解正确的做事方式.

That gives you some food for thought, and some insight into the correct way to do things.