我对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>
}
如果所列学校尚不存在,我会创建一份新的学校文件。学校需要拿一个学生列表/列表(这是我遇到麻烦的地方)。如何将学生添加到新字段(称为注册学生)?
谢谢!
答案 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。