【问题标题】:mongodb update push arraymongodb更新推送数组
【发布时间】:2014-06-07 05:46:19
【问题描述】:

我有以下架构。我正在将 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
}];

我正在尝试将附件推送到文档独有的“附件”数组中。

这是我的查询。

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"
        }
    ]
}

【问题讨论】:

  • 你在这里真正使用的是什么?也许是猫鼬?您的意思是“属性”是您的架构定义吗?还是定义实际上是一个名为“属性”的字段下的附加字段?

标签: node.js mongodb sails.js


【解决方案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));     
    });

【讨论】:

  • 添加一点解释来支持你的回答 Ashokan
【解决方案2】:

再看你的问题,我敢打赌你实际上在这里使用“帆”,即使你的问题没有被标记为这样。

这里的问题是,水线 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 值指定为单个参数意味着您指的是id 查询选择中的值。

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

不过,作为参考,并且已经提到过,您的一般“shell”语法或 MongoDB 特定驱动程序中将支持的内容是这样的,不推荐使用 $pushAll 运算符,并且打算将功能与$push$addToSet 运算符使用 $each 修饰符:

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

所以该语法可以在它适用的地方工作,但对你来说,我认为在“帆”中它不会。

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

【讨论】:

  • 谢谢大家。我尝试了“_id”方法。这也是同样的问题。但我尝试了mongodb保存方法。谢谢大家。
  • @user3046205 所以你在使用风帆?我几乎解释了为什么这是与帆一起使用的唯一方法是检索数据然后操作,然后使用.save()。如果您确认这一点确实会有所帮助,这样我们就可以重新分类您的问题并接受答案,让人们知道有解决方案。
【解决方案3】:

您正在尝试将array 作为元素插入到您的数组中。您可能希望将$pushAll 视为短期解决方案。该运算符已被弃用,但 see here.

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

【讨论】:

  • 嗨马丁,我试过 $pullAll 仍然是同样的问题。请帮助我如何解决这个问题。Tnks
猜你喜欢
  • 1970-01-01
  • 2014-07-29
  • 2016-02-25
  • 2014-07-29
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多