如何连续搜索现有文档并相应地修改/添加每个文档?

时间:2015-07-11 14:14:20

标签: javascript node.js mongodb mongoose

作为一个javascript新手,我在mongodb数据库中连续检查和更新多个文件时遇到了一些麻烦。

为了简要描述main函数,它接收一个item的名称以及一个多个标签的字符串,这些标签被转换为数组。然后,对于每个标记(数组的元素),我想检查集合中是否已存在具有此类名称的文档。如果没有,则应将标签添加到集合中。如果是,则应将添加标记的用户的ID添加到文档中。

所描述的功能如下:

router.post('/saveBand', isAuthenticated, function(req, res){
console.log(req.session.passport.user);
var userId = req.session.passport.user;
var bandName = req.body.title;
var description = req.body.description;
var tags = req.body.tags;
var tagsArray = tags.split(',');
var tagIds = [];

var done = 0;
for (var i=0; i <= tagsArray.length; i++){
    var tagName = tagsArray[i];
    console.log("Saving tag " + tagName);
    Tag.findOne({title: tagName}, function(err, tag){
        if(!err){
            console.log("Saving tag after search: " + tagName);
            if(!tag){
                tag = new Tag();
                tag.title = tagName;
                tag.users = [userId];
                console.log("Saving tag " + tag);
                tagIds.push(tag._id);
                tag.save(function(err){
                    if(!err) {
                        console.log("successfully saved " + tagName);
                    }
                    else {
                        console.log("Error: could not save tag " + tagName);
                    }
                    done++;
                    if(done== tagsArray.length){
                        saveBand();
                    }
                });
            }else{
                if(tag.users.indexOf(userId) < 0){
                    tag.users.push(userId);
                    tag.save(function(err){
                        if(!err) {
                            console.log("successfully saved " + tagName);
                        }
                        else {
                            console.log("Error: could not save tag " + tagName);
                        }
                        done++;
                        if(done== tagsArray.length){
                            saveBand();
                        }
                    });
                }
            }
        }
    });
}
saveBand = function(){
    console.log("all tags saved. Saving band...");
    console.log(bandName);
    var band = new Band({
        title: bandName,
        note: description,
        _owner: userId,
        tags: tagIds
    });
    band.save(function(err){
        if(err){
            console.log(err);
        }
        else{
            console.log("Successfully added band");
        }
        res.redirect("/timeline");
    });
}

例如execition的输出日志如下: 559f9e9d32a642d27e001730

Saving tag band1
Saving tag band2
Saving tag band3
Saving tag undefined
Saving tag after search: undefined
Saving tag { title: undefined,
  _id: 55a12109adbe22a254ab34cc,
  users: [ 559f9e9d32a642d27e001730 ] }
Error: could not save tag undefined
Saving tag after search: undefined
Saving tag { title: undefined,
  _id: 55a12109adbe22a254ab34cd,
  users: [ 559f9e9d32a642d27e001730 ] }
Error: could not save tag undefined
Saving tag after search: undefined
Saving tag { title: undefined,
  _id: 55a12109adbe22a254ab34ce,
  users: [ 559f9e9d32a642d27e001730 ] }
Error: could not save tag undefined
all tags saved. Saving band...
my test band
Saving tag after search: undefined
Saving tag { title: undefined,
  _id: 55a12109adbe22a254ab34d0,
  users: [ 559f9e9d32a642d27e001730 ] }
Error: could not save tag undefined
Successfully added band

从上面的日志中我猜想tagName没有传递给Tag.FindOne()函数。此外,我猜想所需(描述)逻辑的实现并不好。

如果有人可以帮助修改上述函数以检查每个标记是否已经存在并相应地添加/修改它,我将非常感谢。

谢谢。

1 个答案:

答案 0 :(得分:1)

一个问题是for循环从索引0到索引tagsArray.length是4.该数组只有4个条目,所以当它到达tagsArray [4]时它返回undefined。

另一个是来自findOne的回调将在for循环完成迭代并且tagName处于未定义的最终值之后运行。这就是为什么你看到“保存标签未定义”的原因。

您可以通过将for循环更改为forEach来解决这两个问题,例如:

tagsArray.forEach(function(tagName){ ... })