2016-03-22 130 views
0

当用户保存一个问题时,问题可以包含一个“标签”数组。我想获取该数组标签并检查它们是否存在于标签集合中。如果标签存在,更新计数,如果没有,则将其添加到集合中。我有写这样做的代码,但它看起来很冗长。用mongo/mongoose做更好/更简单/更简洁的方法吗?该功能类似于堆栈溢出如何处理标记。MongoDB Mongoose用数组保存或更新

apiRouter.post('/', function(req, res) { 
    var question = new Questions(); 

    question.text = req.body.text; 
    question.answers = req.body.answers; 
    question.tech = req.body.tech; 
    question.tags = req.body.tags; 
    question.level = req.body.level; 
    question.createdAt = req.body.createdAt; 

    question.save(function(err, questions) { 
     if(err) res.send(err); 
     res.json({message: "Question was created."}); 
    }); 

    for each(tag in req.body.tags) { 
     QuestionTags.find({ 'tag': { $regex: new RegExp(tag, "i") } }, function(err, tags) { 
      if(err) res.send(err); 
      if(tags.length === 0) { 
       var tagObj = new QuestionTags(); 
       tagObj = { 
        tag: tag, 
        count: 0 
       } 
       tagObj.save(function(err, questions) { 
        if(err) res.send(err); 
        res.json({message: "Tag created"}); 
       }); 
      } else { 
       var tagObj = new QuestionTags(); 
       tagObj = tags; 

       tagObj.count++; 

       tagObj.save(function(err, questions) { 
        if(err) res.send(err); 
        res.json({message: "Tag updated"}); 
       }) 
      } 
     }) 
    } 
}); 

回答

1

可以使用find()stream()从猫鼬API时使用MongoDB的$in运算符表达式。 find()返回一个Query对象,然后该对象可用于创建一个QueryStream(实现Node.js接口)。然后您可以使用.on来处理每个流事件。

请注意,您不能在$in表达式中使用$regex运算符表达式,因此在将该数组传递到find()之前,必须先处理该表达式。

apiRouter.post('/', function(req, res) { 
    var question = new Questions(); 

    question.text = req.body.text; 
    question.answers = req.body.answers; 
    question.tech = req.body.tech; 
    question.tags = req.body.tags; 
    question.level = req.body.level; 
    question.createdAt = req.body.createdAt; 

    question.save(function(err, questions) { 
     if(err) res.send(err); 
     res.json({message: "Question was created."}); 
    }); 

    var tagsRegExp = []; 

    req.body.tags.forEach(function(tag) { 
     tagsRegExp.push(new RegExp(tag, "i"); 
    } 

    QuestionTags.find({ 'tag': { $in : tagsRegExp }}).stream() 
     .on('error', function(err) { 
      res.send(err); 
     }).on('data', function(tag) { 
      if(tag.length === 0) { 
       var tagObj = new QuestionTags(); 
       tagObj = { 
        tag: tag, 
        count: 0 
       } 
       tagObj.save(function(err, questions) { 
        if(err) res.send(err); 
        res.json({message: "Tag created"}); 
       }); 
      } else { 
       var tagObj = new QuestionTags(); 
       tagObj = tag; 

       tagObj.count++; 

       tagObj.save(function(err, questions) { 
        if(err) res.send(err); 
        res.json({message: "Tag updated"}); 
       }); 
      } 
     }); 
    }); 
+0

这并不完全正常...... QuestionTags.find内的所有内容不再适用,因为它不在forEach中。如果'tagsRegExp'包含6个标签,并且其中5个标签存在于集合中,那么您将在查询响应中找回这5个标签。这对于为不存在的东西创建新标签没有帮助。 – erichardson30

+0

@ erichardson30我更新了从'find()'返回的'Query'对象上使用Mongoose QueryStream的代码和解释。 – roflmyeggo

+0

这不会保存任何问题到questionTags集合 – erichardson30