简体   繁体   中英

Mongodb see if all items in array exist and update else insert

I have a mongo collection of tags and when the user enters an array of tags I want to do the following :

If a tag in the array exists, update the count If a tag in the array does not exist, insert with a count of 0

I currently have :

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

QuestionTags is the mongoose schema for the db collection.

This does not seem to be working. I entered an array of new tags and they are not being added, and the existing tags are not being incremented.

Is there a way to handle this without having to loop through tagArray and make a db call for each item in the array?

UPDATE: Changed my code to this

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

However, newTags is null. QuestionTags collection is currently empty so it should not be null.

I think you can do this in a few queries, without querying in a loop.

1) Update existing tags count : your query works :

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

2) Find new tags :

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

This will give you an array of tags that don't exist in database.

3) Insert new tags using result of 2, in the find callback:

QuestionTags.collection.insertMany(newTagObj);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM