1

I have a collection with a following schema:

{
    "_id" : ObjectId("52dfba46daf02aa4630cf529"),
    "hotelVenue" : {
        "rooms" : [ 
            {
                "clientId" : "ROOM_1",
                "roomName" : "Executive"
            }, 
            {
                "clientId" : "ROOM_2",
                "roomName" : "Premium"
            }
        ]
    }
},
{
    "_id" : ObjectId("52dfc2f9daf02aa2632bc8af"),
    "hotelVenue" : {
        "rooms" : [ 
            {
                "clientId" : "ROOM_1",
                "roomName" : "Studio Room"
            }, 
            {
                "clientId" : "ROOM_2",
                "roomName" : "Soho Suite"
            }, 
            {
                "clientId" : "ROOM_3",
                "roomName" : "Luxury Suite"
            }
        ]
    }
}

I need to genearate unique id for all the records -> subarray. i.e., in the example there is rooms so for each and every room type, I need give a unique id basically using ObjectId().

Output should look something like the below, where roomId being generated.

{
    "_id" : ObjectId("52dfba46daf02aa4630cf529"),
    "hotelVenue" : {
        "rooms" : [ 
            {
                "clientId" : "ROOM_1",
                "roomName" : "Executive",
                "roomId" : "56f8cb3f0c658b4bc26172342"
            }, 
            {
                "clientId" : "ROOM_2",
                "roomName" : "Premium",
                "roomId" : "56f8cb3f0c658b4bc26176d4"
            }
        ]
    }
}

I have written this script where it gives the following error: Error: Line 9: Unexpected token +

db.venues.find().forEach(function(data) 
{
    data.hotelVenue.rooms.forEach(function(roomItem) 
    {
        db.venues.update({_id:data._id,'data.hotelVenue.rooms.clientId' : roomItem.clientId},
        {
            $set:
            {
                'hotelVenue.rooms.'+roomItem.clientId+'.roomId' : ObjectId()
            }
        }); 
    });
})
Sharath
  • 2,348
  • 8
  • 45
  • 81

1 Answers1

1

EDIT: This should do it in a more efficient manner by only saving each document once;

db.venues.
  find({"hotelVenue.rooms": { $elemMatch: {roomId: {$exists: 0}}}}).
  forEach(function(doc) {
    doc.hotelVenue.rooms.forEach(function(room) {
      if(!room.roomId) {
        room.roomId = ObjectId();
      }
    }); 
    db.venues.save(doc);
  });

The find filters out only documents that are in need of updating. After that, it's just a matter of updating the document as needed and calling save.

Of course, backups are in order before running potentially destructive queries from random people on the Internet against your production data set.

Joachim Isaksson
  • 176,943
  • 25
  • 281
  • 294