【问题标题】:pushing object into array schema in Mongoose将对象推入 Mongoose 中的数组模式
【发布时间】:2013-03-15 08:34:15
【问题描述】:

我有这个猫鼬模式

var mongoose = require('mongoose');

var ContactSchema = module.exports = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  phone: {
    type: Number,
    required: true,
    index: {unique: true}
  },
  messages: [
  {
    title: {type: String, required: true},
    msg: {type: String, required: true}
  }]
}, {
    collection: 'contacts',
    safe: true
});

并尝试通过这样做来更新模型:

Contact.findById(id, function(err, info) {
    if (err) return res.send("contact create error: " + err);

    // add the message to the contacts messages
    Contact.update({_id: info._id}, {$push: {"messages": {title: title, msg: msg}}}, function(err, numAffected, rawResponse) {
      if (err) return res.send("contact addMsg error: " + err);
      console.log('The number of updated documents was %d', numAffected);
      console.log('The raw response from Mongo was ', rawResponse);

    });
  });

我不是声明 messages 来获取对象数组吗?
错误: MongoError:无法将 $push/$pushAll 修饰符应用于非数组

有什么想法吗?

【问题讨论】:

  • 您收到什么错误信息? “我似乎无法正确处理 $push”是什么意思?
  • MongoError: 无法将 $push/$pushAll 修饰符应用于非数组
  • 不确定这是否能解决问题,但请尝试去掉 [{title: title, msgs: [msg]}] 周围的方括号。 $push 接受单个值。
  • 我的猜测是您最初将消息添加为非数组
  • @user1460015 请将您的问题标记为已解决。

标签: mongodb mongoose


【解决方案1】:

在数组中推送数据有两种方式

第一种方式:

let newMessage = {title: "new title", msg: "new Message"}
let result = await Contact.findById(id);
result.messages.push(newMessage);
await result.save();

第二种方式

let result = await Contact.findByIdAndUpdate(
        id,
        {$push: {"messages": {title: title, msg: msg}}},
        {upsert: true, new : true})

【讨论】:

    【解决方案2】:

    mongoose 在一次操作中为您完成此操作。

    Contact.findByIdAndUpdate(
        info._id,
        {$push: {"messages": {title: title, msg: msg}}},
        {safe: true, upsert: true},
        function(err, model) {
            console.log(err);
        }
    );
    

    请记住,使用这种方法,您将无法使用架构的“pre”功能。

    http://mongoosejs.com/docs/middleware.html

    从最新的 mogoose findbyidandupdate 开始,需要添加一个“new : true”可选参数。否则,您会将旧文档退还给您。因此,Mongoose 版本 4.x.x 的更新转换为:

    Contact.findByIdAndUpdate(
            info._id,
            {$push: {"messages": {title: title, msg: msg}}},
            {safe: true, upsert: true, new : true},
            function(err, model) {
                console.log(err);
            }
        );
    

    【讨论】:

    • @TejasManohar 只是为了表明您可以在其中包含多个选项。
    • 这个答案对我帮助很大。但是safeupsertnew 这些选项有什么用?
    • "new" - 以便您获得更新的文档作为回报(阅读答案描述)“upsert” - 可选。如果设置为 true,则在没有文档与查询条件匹配时创建一个新文档。默认值为 false,即在未找到匹配项时不插入新文档。 docs.mongodb.org/manual/reference/method/db.collection.update“安全”-stackoverflow.com/questions/4974686/…
    • 感谢您的真实回答:)
    • safe 未包含在 .findOneAndUpdate() 的文档中
    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 2015-11-14
    • 2019-04-08
    • 2017-09-30
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多