Update array in Mongodb subdocument

Asked

Viewed 308 times

1

I’m trying to do an update here on mongoshell and I’m having a hard time.

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 making:

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 on Mongo the same does not give error. I already made sure that it falls inside the foreach and and and search my data in the field correctly, the problem is only the update that does not work.

Thank you!

1 answer

0

I haven’t used it yet Bulk but in normal updates, like db.mycollection.update(query, updates, {multi: true}) you can only use the $ when the predicate (query) refers to some attribute within the array. Another thing is that you cannot refer to other attributes of the same document by name as you tried to 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);

    // ...
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.