Node.js mongoose如果新引用则保存
如果您想用两个词来了解此线程中的问题:我正在尝试完成mongoose函数findOrAdd():如果我搜索的Id不存在,我应该添加一个新文档。在这之后(这就是为什么我需要一些同步函数),我需要根据新的ObjectID执行另一个查询。 这是我的帖子模式Node.js mongoose如果新引用则保存,node.js,mongodb,mongoose,bootstrap-tokenfield,Node.js,Mongodb,Mongoose,Bootstrap Tokenfield,如果您想用两个词来了解此线程中的问题:我正在尝试完成mongoose函数findOrAdd():如果我搜索的Id不存在,我应该添加一个新文档。在这之后(这就是为什么我需要一些同步函数),我需要根据新的ObjectID执行另一个查询。 这是我的帖子模式 var com_post_schema = new Schema({ content: { type: String, required: true }, postedBy: [{ type: mongoose.Schema.Types.O
var com_post_schema = new Schema({
content: { type: String, required: true },
postedBy: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'com_user'
}]
});
和我的用户模式
var com_user_schema = new Schema({
name: { type: String, required: true },
age: {type:Number}
});
因此,一篇文章可以有多个作者。
我的问题:作者可以是现有用户(在bootstrap tokenfield中选择)或新用户,请参见以下json示例:
{
"content":"post content",
"postedBy":[
{
"_id":"56a60a972b70225014753d1a",
"name":"Paul",
"age":20,
"__v":0,
"value":"Paul",
"label":"Paul"
},
{
"value":"John",
"label":"John"
}
]
}
用户Paul已经存在于'com_user'集合中,我必须在'com_user'中保存用户John,然后使用两个用户objectid refs保存帖子(字段'value'和'label'由bootstrap tokenfield发送)。
我不清楚我该怎么做
编辑这是我当前的代码,我仍然有同步问题。我做了一些测试,在控制台中随机看到“添加了新帖子”和“未找到用户…”
尝试使用3个用户,然后查看
app.post('/api/community/posts', function(req,res){
var arr=[],i=0;
req.body.postedBy.forEach(function(el){
com_user.findById(el._id, function (err, user) {
if(user) {
console.log("User found!");
console.log(user);
arr.push(mongoose.Types.ObjectId(user._id ));
i++;
if(i==req.body.postedBy.length-1) {
console.log('UFi'+i)
console.log(arr)
var com_post1= new com_post({
content:req.body.content,
postedBy:arr,
});
com_post1.save(function(err){
if(!err){
console.log("New post added!");
res.json({"New post added! ":req.body.content});
}
else {
res.json({"Error adding post":'error'});
error(err)
}
});
}
}
else {
var com_user1= new com_user({
name:el.label,
age: 20
});
com_user1.save(function(err,newuser){
if(err)
console.log(err)
else {
console.log('User not found and just added!');
console.log(newuser)
arr.push(mongoose.Types.ObjectId(newuser._id));
console.log(arr)
i++;
if(i==req.body.postedBy.length-1) {
console.log('NUFi'+i)
console.log(arr)
var com_post1= new com_post({
content:req.body.content,
postedBy:arr,
});
com_post1.save(function(err){
if(!err){
console.log("New post added!");
res.json({"New post added! ":req.body.content});
}
else {
res.json({"Error adding post":'error'});
error(err)
}
});
}
}
});
}
});
});
});
这是因为forEach之后的代码在forEach完成之前执行。像这样试试
app.post('/api/community/posts', function(req,res){
var arr=[],i=0;
req.body.postedBy.forEach(function(el){
com_user.findById(el._id, function (err, user) {
if(user) {
console.log("User found!");
console.log(user);
arr.push(mongoose.Types.ObjectId(user._id ));
i++;
if(i==req.body.postedBy.length-1) { //to ensure forEach is complete
console.log(arr)
var com_post1= new com_post({
content:req.body.content,
postedBy:arr,
});
com_post1.save(function(err){
if(!err)
res.json({"New post added! ":req.body.content});
else {
res.json({"Error adding post":'error'});
error(err)
}
});
}
}
else {
var com_user1= new com_user({
name:el.label,
age: 20
});
com_user1.save(function(err,newuser){
if(err)
console.log(err)
else {
console.log('User not found and just added!');
console.log(newuser)
arr.push(mongoose.Types.ObjectId(newuser._id));
i++;
if(i==req.body.postedBy.length-1) {
console.log(arr)
var com_post1= new com_post({
content:req.body.content,
postedBy:arr,
});
com_post1.save(function(err){
if(!err)
res.json({"New post added! ":req.body.content});
else {
res.json({"Error adding post":'error'});
error(err)
}
});
}
}
});
}
});
})) 谢谢,我明白你的意思。四处搜索我发现同步处理node.js函数是一个常见的错误,我明白了,它都是异步的。但由于这是一个简单的例子,我的实际项目每个模式有30个字段,其中几乎一半是此类字段(引用数组),我想我需要另一种解决方案,而不是这种检查,我会避免每个查询使用300行函数:)我做了一些测试(使用多个用户),有时我还是在用户之前添加帖子。也许这是一个解决方案,我不确定。好的,我只是注意到你所做的更改。您必须使用不同的变量“i”作为计数器,而不是forEach索引变量i。在这段代码中,forEach不会等待内部的查询执行。这就是为什么我使用了一个单独的变量i,并在得到查询结果后将其递增。