Update array in subdocument MongoDB

1

I'm trying to do an update here in the mongoshell and I'm having trouble.

I have the following json:

{

"_id" : ObjectId("56cc03c16f4e85f538ef79ae"),
"contact_id" : NumberLong(1000295524418),
"gender" : 1,
"phonetic_gender" : 1,
"first_name" : "LEANDRO",
"score" : 44,
"address" : [ 
    {
        "address_id" : NumberLong(2634224807),
        "rank" : 201604.0,
        "score" : 7.0,
        "street_type" : "AV",
        "street_title" : "DA",
        "street" : "EMILIA DE CASTRO MARTINS",
        "number" : 34.0,
        "district" : "JARDIM BELA VISTA",
        "city" : "GUARULHOS",
        "state" : "SP",
        "zip_code" : 7132470.0,
        "create_date" : ISODate("2014-08-07T00:00:00.000Z"),
        "update_date" : ISODate("2016-05-03T00:00:00.000Z")
    }, 
    {
        "address_id" : NumberLong(2634735566),
        "rank" : 201410,
        "score" : 10,
        "street_type" : "AV",
        "street_title" : "DA",
        "street" : "EMILIA DE CASTRO MARTINS",
        "district" : "JARDIM BELA VISTA",
        "city" : "GUARULHOS",
        "state" : "SP",
        "zip_code" : "07132470",
        "create_date" : ISODate("2014-08-07T03:00:00.000Z"),
        "update_date" : ISODate("2014-08-07T03:00:00.000Z")
    }
]}

I need to go through all my documents and update the type of the rank and score field in the address array.

See the following code I'm doing:

var total = 0
var skip = 0
var total_adress = db.company.count() - skip
var bulk = db.person.initializeUnorderedBulkOp()
var person = db.getCollection('Person').find( {$and:[ {"contact_id":1000295524418}).addOption(DBQuery.Option.noTimeout).forEach(
function(person){
        var contact_id = person.contact_id.valueOf()
            bulk.find(
                { contact_id: contact_id  }
            ).update(
                { 
                    $set: {
                        "address.$.zip_code":"address.zip_code".toString(),
                        "address.$.rank": NumberInt("address.rank"),
                        "address.$.number": "address.number".toString(),
                        "address.$.score": NumberInt("address.score") - 2
                    }
                } 
            );


    if((++total % 1000) === 0){
        print("Total person....: " + total_adress)
        print("Iniciando bulk..: " + Date())
        bulk.execute({ w: 0 })
        bulk = db.company.initializeUnorderedBulkOp()
        print("Fim bulk........: " + Date())
        print("#############################################################################")
    }
}); bulk.execute();  print(total);

Now comes the problem, when I run this command in Mongo the same does not give error. I already made sure that it falls into the foreach and fetches my data in the field correctly, the problem is just the update that does not work.

Thank you!

    
asked by anonymous 01.09.2016 / 16:25

1 answer

0

I have not yet used Bulk but in normal updates, type db.mycollection.update(query, updates, {multi: true}) you can only use $ when the predicate ( query ) refers to some attribute within the array. Another thing is that you can not refer to other attributes of the same document by name as you tried in "address.zip_code".toString() .

I think you need something more manual, like:

function(person){
    var contact_id = person.contact_id.valueOf(),
        updates = { $set: {}};
        person.address.forEach(function(addr, i){
            updates.$set['address.' + i + '.zip_code'] = addr.zip_code.toString();
            updates.$set['address.' + i + '.rank'] = NumberInt(addr.rank);
            updates.$set['address.' + i + '.number'] = addr.number ? addr.number.toString() : null;
            updates.$set['address.' + i + '.score'] = NumberInt(addr.score);
        });

        bulk.find({ contact_id: contact_id  }).update(updates);

    // ...
}
    
08.09.2016 / 22:46