将新字段添加到文档mongodb

时间:2013-11-08 21:09:54

标签: javascript mongodb meteor

我对mongodb很新,并且有一个我遇到麻烦的基本问题。如何获取已创建文档的ID字段?我需要ID,所以我可以更新/添加一个新字段到文档。

//newProfile is an object, one string it holds is called school
if(Schools.find({name: newProfile.school}).fetch().length != 1){
    var school = {
        name: newProfile.school
    }
    Meteor.call('newSchool', school);

    //Method 1 (doesn't work)
    var schoolDoc = Schools.findOne({name: newProfile.school});
    Schools.update({_id: schoolDoc._id}, {$set: {enrolledStudents: Meteor.user()}});

    //Method 2?
    //Schools.update(_id: <what goes here?>, {$push: {enrolledStudents: Meteor.user()}});
}
else {
    //Schools.update... <add users to an existing school>
}

如果所列学校尚不存在,我会创建一份新的学校文件。学校需要拿一个学生列表/列表(这是我遇到麻烦的地方)。如何将学生添加到新字段(称为注册学生)?

谢谢!

3 个答案:

答案 0 :(得分:0)

对于你想要做的事情,没有必要得到_id。当您使用update时,只需使用您的查询切换{_id: schoolDoc._id}即可。看起来使用{name: newProfile.school}会起作用,假设您的其余代码完成了您希望它执行的操作。

虽然这适用于普通的Mongo驱动程序,但我发现Meteor不允许您的更新查询为_id以外的任何内容:Meteor throws throwIfSelectorIsNotId exception

首先,确保你正在拉正确的文件,你可以尝试这样的事情:

var school_id = Schools.findOne({name: newProfile.school})._id;
Schools.update({_id: school_id}, { $push: { enrolledStudents: Meteor.user()}});

如果这不起作用,你将不得不做一些调试,看看它有什么特别之处。

答案 1 :(得分:0)

我很难理解你正在尝试做什么。到目前为止,这是我的分析和理解,引用了几个指针:

if(Schools.find({name: newProfile.school}).fetch().length != 1){

这会更有效率

if(Schools.find({name: new Profile.school}).count() != 1) {

Meteor.call('newSchool', school);

不确定你在这里做什么,除非你将异步运行,这意味着在执行此代码块的其余部分时,很可能在服务器端没有完成此Meteor.call()功能。

//Method 1 (doesn't work)
var schoolDoc = Schools.findOne({name: newProfile.school});
Schools.update({_id: schoolDoc._id}, {$set: {enrolledStudents: Meteor.user()}});

根据代码顶部的if语句判断,数据库中有多个具有此名称的学校。所以我不确定schoolDoc变量是否是您追踪的记录。

答案 2 :(得分:0)

我认为你遇到了麻烦,因为客户端上的Meteor.call具有异步特性。

尝试做这样的事情:

// include on both server and client
Meteor.methods({
  newSchool: function (school) {
    var newSchoolId,
        currentUser = Meteor.user();
    if (!currentUser) throw new Meteor.Error(403, 'Access denied');

    // add some check here using the Meteor check/match function to ensure 'school'
    // contains proper data

    try {
      school.enrolledStudents = [currentUser._id];
      newSchoolId = Schools.insert(school);
      return newSchoolId;
    } catch (ex) {
      // handle appropriately
    }
  }
});


// on client
var schoolExists = false;

if (Schools.findOne({name: newProfile.school})) {
  schoolExists = true;
}

if (schoolExists) {
  var school = {
        name: newProfile.school
      };
  Meteor.call('newSchool', school, function (err, result) {
    if (err) {
      alert('An error occurred...');
    } else {
      // result is now the _id of the newly inserted record
    }
  })
} else {

}

在客户端和服务器上都包含该方法允许Meteor进行延迟补偿并立即在客户端上“模拟”插入,而无需等待服务器往返。但您也可以将该方法保留在服务器端。

您应该在服务器上执行注册的学生部分,以防止恶意用户弄乱您的数据。此外,您可能不希望实际将整个用户对象存储在enrolledStudents数组中,只是用户_id。

相关问题