-1

I have documents in the following format:

{
  _id: "1232014",
  account: "123",
  year: 2014,
  country: 826
}

The _id field is made up of the account field and the year field combined.

However, I've since found that the same account in the same year can have data in different countries, and I'm getting a duplicate key error.

What I need to do is have the country field as part of the _id field too e.g.

_id: "1232014826"

Since I'm using a value from within the document as part of the update, I don't think I can use $set, so I've tried to use save() within a forEach() query instead:

db.account_data.find({"_id" : "1232014"}).forEach(function(doc) {
    doc._id = doc._id + doc.country;
    db.collection.save(doc);
});

This isn't working.

Is there any way to update _id? Or is this impossible because it is primary key field?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
finoutlook
  • 2,523
  • 5
  • 29
  • 43
  • @JoachimIsaksson and possibly not because it is actually a really awful answer. Let's try and remove the old and bad answers and replace them with better ones. – Neil Lunn Apr 17 '14 at 10:13
  • I see now this is a similar question to the other one you mention. Hopefully the question has more detail and context, and could be useful if other people have the same issue. It was actually the non-accepted answer to that question which related best to what I needed. – finoutlook Apr 17 '14 at 10:36

1 Answers1

2

Yes it is impossible because it is a primary key field. If you actually want to do this then what you are actually doing is inserting a new document and removing the old one:

db.account_data.find({"_id" : "1232014"}).forEach(function(doc) {
    var oldId = doc._id;
    var doc._id = doc._id + doc.country;
    db.collection.remove({ _id: oldId });
    db.collection.save(doc);
});
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • Thanks, this is the answer I needed, and I guess I can just remove the `.find()` argument to update the whole collection. – finoutlook Apr 17 '14 at 10:34
  • 1
    When I ran the query, I ended up having some items with the country appended multiple times! e.g. `1232014826826826826826`. I don't know if this was because the `doc._id` was being set as itself in a way that caused some kind of recursive bug. To fix I ran the query with the _id being created from scratch i.e. `var doc._id = doc.account + doc.year + doc.country;` which worked fine. Any thoughts on this appreciated. – finoutlook Apr 17 '14 at 16:47