将对象推入 Mongoose 中的数组模式

Posted

技术标签:

【中文标题】将对象推入 Mongoose 中的数组模式【英文标题】:pushing object into array schema in 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 请将您的问题标记为已解决。 【参考方案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“安全”-***.com/questions/4974686/… 感谢您的真实回答:) safe 未包含在 .findOneAndUpdate() 的文档中

以上是关于将对象推入 Mongoose 中的数组模式的主要内容,如果未能解决你的问题,请参考以下文章

推入 Mongoose 数组不会更新数组

Mongoose:将字符串推入数组

Mongoose/Node:将元素推入数组类型的文档字段?

mongoose.findByIdAndUpdate 只会保存被推入数组的对象的第一个键值

mongoose.findByIdAndUpdate 只会保存被推入数组的对象的第一个键值

如何使用 $push (Mongoose) 在数组中推送多个对象