1

I am trying to insert a bunch of arrays into mongoDB.

The data looks something like:

var places = {
    city: ['london', 'york', 'liverpool'],
    country: ['uk', 'france']
};

Each time I add an array, some of the entries could already be there, so I want to ensure there are no duplicates.

db.collection('places').ensureIndex({'city': 1}, {unique: true }, function(){ });
db.collection('places').ensureIndex({'country': 1}, {unique: true }, function(){ });

I then need to loop through the places object and add each item:

for(var key in places){

    db.collection('places').update({_id: 1}, { $addToSet: { key: { $each places[key] } } }, function(err, docs){
        if(err){
            console.log(err);
        }else{
            console.log('success');
        }
    });

}

Here I need key to be the actual keys: 'city', 'country'. Rather than literally being 'key'. But I cant see how this can be achieved with with the modifiers in place.

6
  • It is probably a stupid question, but why don't you add an empty array to every document so you don't have this problem? :) Commented Jan 25, 2015 at 11:55
  • Could you expand on this please? Commented Jan 25, 2015 at 11:57
  • Hmm, I am beginning to think I misunderstood your question. Do you want to make sure that the content of your city/country array is unique or do you want to make sure there is only one array of city/country in your document? Commented Jan 25, 2015 at 11:59
  • I want to ensure the content of the city/country array is unique. Sorry I should actually be specifying and id in the update to ensure im updating the same arrays. Commented Jan 25, 2015 at 12:02
  • You are indeed correct that you will need to specify your _id as your first selector. The rest of your code seems about right. Let me know if you are stil having problems. Commented Jan 25, 2015 at 12:06

1 Answer 1

2

You need to build up your $addToSet value programmatically:

for(var key in places){
    var addToSet = {};
    addToSet[key] = { $each: places[key] };
    db.collection('places').update({_id: 1}, {$addToSet: addToSet}, function(err, docs){
        if(err){
            console.log(err);
        }else{
            console.log('success');
        }
    });
}

But you can do this more efficiently by combining both updates into one:

var addToSet = {};
for(var key in places){
    addToSet[key] = { $each: places[key] };
}
db.collection('places').update({_id: 1}, {$addToSet: addToSet}, function(err, docs){
    if(err){
        console.log(err);
    }else{
        console.log('success');
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome that it can be done in a single query. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.