通过mongoose将项目推送到mongo数组

时间:2015-10-10 02:43:41

标签: node.js mongodb express mongoose

我已经仔细搜索了一下,但是我确信我找不到正确的词语来描述我之后的事情。

基本上我有一个名为“人物”的mongodb系列。 该集合的架构如下:

people: {
         name: String, 
         friends: [{firstName: String, lastName: String}]
        }

现在,我有一个非常基本的快速应用程序连接到数据库并成功创建了“人员”。一个空的朋友阵列。

在应用程序的辅助位置,有一个表单可以添加朋友。表单接受firstName和lastName,然后使用名称字段POST,以便引用正确的人员对象。

我很难做的是创建一个新的朋友对象,然后推动"它进了朋友阵列。

我知道当我通过mongo控制台执行此操作时,我在查找条件之后使用$ push作为我的第二个参数的更新函数,但我似乎无法找到让mongoose这样做的合适方法

db.people.update({name: "John"}, {$push: {friends: {firstName: "Harry", lastName: "Potter"}}});

更新: 所以,阿德里安的回答非常有帮助。以下是我为实现目标所做的工作。

在我的app.js文件中,我使用

设置了一个临时路由
app.get('/addfriend', users.addFriend);

在我的users.js文件中我有

exports.addFriend = function (req, res, next)
{
var friend = {"firstName": req.body.fName, "lastName": req.body.lName};
Users.findOneAndUpdate({name: req.user.name}, {$push: {friends: friend}});
};

8 个答案:

答案 0 :(得分:166)

假设var friend = { firstName: 'Harry', lastName: 'Potter' };

您有两种选择:

在内存中更新模型,并保存(plain javascript array.push):

person.friends.push(friend);
person.save(done);

PersonModel.update(
    { _id: person._id }, 
    { $push: { friends: friend } },
    done
);

我总是尝试在可能的情况下选择第一个选项,因为它会更多地尊重猫鼬给你带来的好处(钩子,验证等)。

但是,如果你正在进行大量的并发写入,那么你将遇到竞争条件,你最终会遇到令人讨厌的版本错误,以阻止你每次更换整个模型并丢失你添加的前一个朋友。因此,只有在绝对必要时才会去前者。

答案 1 :(得分:20)

  

$push运算符将指定值附加到数组。

{ $push: { <field1>: <value1>, ... } }
  

$push添加数组字段,并将值作为元素。

以上答案符合所有要求,但我通过以下方式开展工作

var objFriends = { fname:"fname",lname:"lname",surname:"surname" };
Friend.findOneAndUpdate(
   { _id: req.body.id }, 
   { $push: { friends: objFriends  } },
  function (error, success) {
        if (error) {
            console.log(error);
        } else {
            console.log(success);
        }
    });
)

答案 2 :(得分:4)

使用$push更新文档并在数组中插入新值。

查找:

db.getCollection('noti').find({})

查找结果:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

更新:

db.getCollection('noti').findOneAndUpdate(
   { _id: ObjectId("5bc061f05a4c0511a9252e88") }, 
   { $push: { 
             graph: {
               "date" : ISODate("2018-10-24T08:55:13.331Z"),
               "count" : 3.0
               }  
           } 
   })

更新结果:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }, 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 3.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

答案 3 :(得分:1)

就我而言,我做到了

  const eventId = event.id;
  User.findByIdAndUpdate(id, { $push: { createdEvents: eventId } }).exec();

答案 4 :(得分:0)

一种简单的方法是使用以下内容:

var John = people.findOne({name: "John"});
John.friends.push({firstName: "Harry", lastName: "Potter"});
John.save();

答案 5 :(得分:0)

首先我尝试了这段代码

const peopleSchema = new mongoose.Schema({
  name: String,
  friends: [
    {
      firstName: String,
      lastName: String,
    },
  ],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
  name: "Yash Salvi",
  notes: [
    {
      firstName: "Johnny",
      lastName: "Johnson",
    },
  ],
});
first.save();
const friendNew = {
  firstName: "Alice",
  lastName: "Parker",
};
People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
  function (error, success) {
    if (error) {
      console.log(error);
    } else {
      console.log(success);
    }
  }
);

但是我注意到只有第一个朋友(即Johhny Johnson)得到了保存,并且在现有“朋友”数组中推送数组元素的目标似乎不像我运行代码时那样起作用,数据库中的代码仅显示“ “第一个朋友”和“朋友”数组只有一个元素! 所以简单的解决方案写在下面

const peopleSchema = new mongoose.Schema({
  name: String,
  friends: [
    {
      firstName: String,
      lastName: String,
    },
  ],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
  name: "Yash Salvi",
  notes: [
    {
      firstName: "Johnny",
      lastName: "Johnson",
    },
  ],
});
first.save();
const friendNew = {
  firstName: "Alice",
  lastName: "Parker",
};
People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
  { upsert: true }
);

添加“ {upsert:true}”解决了我的问题,保存了代码并运行它后,我看到“ friends”数组现在有2个元素! upsert = true选项创建不存在的对象。 默认设置为false。

如果不起作用,请在以下代码段中使用

People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
).exec();

答案 6 :(得分:-1)

我也遇到了这个问题。我的解决方法是创建子模式。请参阅下面的模型示例。

----人物模型

const mongoose = require('mongoose');
const SingleFriend = require('./SingleFriend');
const Schema   = mongoose.Schema;

const productSchema = new Schema({
  friends    : [SingleFriend.schema]
});

module.exports = mongoose.model('Person', personSchema);

***重要提示:SingleFriend.schema - &gt;确保使用小写的模式

---子模式

const mongoose = require('mongoose');
const Schema   = mongoose.Schema;

const SingleFriendSchema = new Schema({
  Name: String
});

module.exports = mongoose.model('SingleFriend', SingleFriendSchema);

答案 7 :(得分:-1)

使用Mongoose将项目推入数组的另一种方法是- $ addToSet ,如果您只希望将唯一的项目推入数组。 $ push 运算符只是将对象添加到数组中,无论对象是否已经存在,而 $ addToSet 仅在对象不存在于数组中时这样做包含重复性。

Hello
Hello = 10
Hello
Hello = 10

这将查找要添加到数组的对象。如果找到,则不执行任何操作。如果没有,请将其添加到数组中。

参考: https://docs.mongodb.com/manual/reference/operator/update/addToSet/ https://mongoosejs.com/docs/api/array.html#mongoosearray_MongooseArray-addToSet