【问题标题】:Mongodb see if all items in array exist and update else insertMongodb查看数组中的所有项目是否存在并更新其他插入
【发布时间】:2016-03-25 00:36:39
【问题描述】:

我有一个 mongo 标签集合,当用户输入一个标签数组时,我想要执行以下操作:

如果数组中存在标签,则更新计数 如果数组中的标签不存在,则插入计数为0

我目前有:

QuestionTags.update({'tag': {$in: tagArray}}, {$inc : {'count': +1} }, { upsert: true });

QuestionTags 是 db 集合的猫鼬模式。

这似乎不起作用。我输入了一个新标签数组,它们没有被添加,现有标签也没有被增加。

有没有一种方法可以处理这个问题,而不必遍历 tagArray 并对数组中的每个项目进行 db 调用?

更新: 将我的代码更改为此

QuestionTags.update({'tag': {$in: req.body.tags}}, {$inc : {'count': +1} }, { upsert: true, multi: true });
QuestionTags.find({'tag' :{$nin: req.body.tags}}, function(err, newTags) {
    console.log("New Tags :" + newTags);
    var tagArray = [];
    newTags.forEach(function(tag){
        var tagObj = {
            tag: tag,
            count: 1
        }
        tagArray.push(tagObj);
    });
    QuestionTags.collection.insert(tagArray);
});

但是,newTags 为空。 QuestionTags 集合当前为空,因此不应为空。

【问题讨论】:

  • 你的 tagArray 中有什么?简单的字符串?我刚刚做了一个测试,增量适用于您的更新查询。对于插入,您的更新对象(更新的第二个参数)中没有 $set: {tag: 'newTag'},因此 upsert 实际上并没有插入任何内容。
  • @Komo 是的,它只是简单的字符串 ["Java"、"JavaScript"、"Agile"]。如果其他一切正常,您可以发布一个正确的解决方案
  • @Komo 你发布的解决方案没有用吗?
  • 很遗憾,不,我认为没有办法通过查询 mongo 来“过滤”数组而不做循环
  • 我发布了一个新答案,希望适合你

标签: javascript node.js mongodb express mongoose


【解决方案1】:

我认为您可以在几个查询中完成此操作,而无需循环查询。

1) 更新现有标签计数:您的查询有效:

QuestionTags.update({'tag': {$in: tagArray}}, {$inc : {'count': +1} },{multi: true} );

2) 查找新标签:

QuestionTags.find({},function(err, tags) {
    var newTagObj = [];

    // tags is originally an array of objects
    // creates an array of strings (just tag name)
    tags = tags.map(function(tag) {
        return tag.tag;
    });

    // returns tags that do not exist
    var newTags = tagArray.filter(function(tag) {
        // The count = 1 can be done here
        if (tags.indexOf(tag) < 0) {
            tag.count = 1;
        }

        return tags.indexOf(tag) < 0;
    });

    // creates tag objects with a count of 1
    // adds to array
    // (this can be done in the previous loop)
    newTags.forEach(function(tag) {
        var tagObj = {
            tag: tag,
            count: 1
        }
        newTagObj.push(tagObj);
    });

这将为您提供数据库中不存在的标签数组。

3) 在 find 回调中使用 2 的结果插入新标签:

QuestionTags.collection.insertMany(newTagObj);

【讨论】:

  • 总体来说效果很好。但是,计数似乎没有更新。即使标签具有相同的“标签”属性,它也只是每次都插入新记录。
  • 嗯,您是否删除了更新查询中的 upsert 选项?至少它不应该添加新记录。
  • 是的,更新查询与此相同。不知道为什么它不起作用。我在更新之前、过滤器之前注销了 tagArray,然后是新标签,它们都包含相同的项目
  • 这很奇怪,也许你可以在你的mongo终端db.QuestionTags.find({ tag: { $in: ['tag1','tag2'] } })中运行一个find,看看更新查询的查询对象是否真的找到了什么
  • 是的,它让我返回所有行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2021-10-09
  • 2021-08-24
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多