2016-02-01 4 views
2

Если вы хотите узнать, в чем проблема в этой теме в двух словах: Я пытаюсь выполнить функцию mongoose findOrAdd(): если идентификатор, который я ищу, отсутствует, Я должен добавить новый документ. После этого (вот почему мне нужны некоторые функции синхронизации) мне нужно сделать другой запрос на основе новых ObjectIds.mongoose save if new refs

Это мое сообщение Schema

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} 
}); 

Так пост может иметь более одного автора. Моя проблема: автор может быть существующий пользователь (выбирается в бутстраповской-tokenfield) или новый пользователь, увидеть этот JSon пример:

{ 
    "content":"post content", 
    "postedBy":[ 
     { 
     "_id":"56a60a972b70225014753d1a", 
     "name":"Paul", 
     "age":20, 
     "__v":0, 
     "value":"Paul", 
     "label":"Paul" 
     }, 
     { 
     "value":"John", 
     "label":"John" 
     } 
    ] 
} 

Пользователь Пол уже присутствует в коллекции «com_user», я должен сохраните пользователя John в 'com_user', а затем сохраните сообщение с обоими объектами ObjectIds refs (значения полей 'и' label 'отправлены с помощью bootstrap-tokenfield). Я не понимаю, как это сделать.

EDITэто мой текущий код У меня все еще есть проблемы с синхронизацией. Я сделал несколько тестов, и я вижу в случайном порядке консоли «Новое сообщение добавлено», а затем «Пользователь не найден ..»

Попробуйте с 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) 
          } 
         }); 
        } 
       } 
      }); 
     } 
    }); 

}); 
}); 
+0

Хорошо, я только что заметил изменение, которое вы сделали. Вы должны использовать другую переменную «i» в качестве счетчика, а не индексную переменную i. В этом коде forEach не ожидает выполнения запросов внутри. Вот почему я использовал отдельную переменную i и увеличил ее после получения результата запроса. – Nijeesh

ответ

2

его, потому что код после 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) 
          } 
         }); 
        } 
       } 
      }); 
     } 
    }); 

});

+0

спасибо, я вижу вашу точку. Поиск вокруг я вижу, что это распространенная ошибка, обрабатывающая функции node.js синхронно, я получаю ее, это все async. Но, поскольку это простой пример, у моего реального проекта есть ~ 30 полей на Схему, и почти половина из них такого типа (массив ссылок), мне кажется, мне нужно другое решение, чем эта проверка, я бы избегал 300 строк function every query :) – alfredopacino

+0

i отредактировал первый код сообщения – alfredopacino

+0

, какую ошибку вы получаете для нового пользователя? – Nijeesh