0

I've this document:

{
        "_id" : ObjectId("54140782b6d2ca6018585093"),
        "user_id" : ObjectId("53f4ae1ae750619418a20467"),
        "date" : ISODate("2014-09-13T08:59:46.709Z"),
        "type" : 0,
        "tot" : 2,
        "additional_info" : {
                "item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
                "shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
                "ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
        },
        "transactions" : [
                {
                        "_id" : ObjectId("54140782b6d2ca6018585091"),
                        "date_creation" : ISODate("2014-09-13T08:59:46.711Z"),
                        "type" : -1
                },
                {
                        "_id" : ObjectId("54140782b6d2ca6018585092"),
                        "date_creation" : ISODate("2014-09-13T08:59:46.788Z"),
                        "type" : 1
                }
        ]
}

and I need to add 2 more field to the first transaction opbject: - date_execution: date - result: this bson document

{ "server_used" : "xxx.xxx.xxx.xxx:27017" , "ok" : 1 , "n" : 1 , "updated_executed" : true} (m_OR.getDocument() in the following code example)

to obtaing that document

    {
        "_id" : ObjectId("54140811b6d25137753c1a1a"),
        "user_id" : ObjectId("53f4ae1ae750619418a20467"),
        "date" : ISODate("2014-09-13T09:02:09.098Z"),
        "type" : 0,
        "tot" : 2,
        "additional_info" : {
                "item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
                "shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
                "ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
        },
        "transactions" : [
                {
                        "_id" : ObjectId("54140811b6d25137753c1a18"),
                        "date_creation" : ISODate("2014-09-13T09:02:09.100Z"),
                        "type" : -1,
                        "result" : {
                                "server_used" : "xxx.xxx.xxx.xxx:27017",
                                "ok" : 1,
                                "n" : 1,
                                "updated_executed" : true
                        },
                        "date_execution" : ISODate("2014-09-13T09:02:15.370Z")
                },
                {
                        "_id" : ObjectId("54140811b6d25137753c1a19"),
                        "date_creation" : ISODate("2014-09-13T09:02:09.179Z"),
                        "type" : 1
                }
        ]
}

The only way I was able to do that is the do 2 separates updates (update is a my wrapper funciont that execute the real updates in mongodb and it works fine):

    // where
    BasicDBObject query = new BasicDBObject();
    query.append("transactions._id", m_Task.ID());

    // new value for result - 1st upd
    BasicDBObject value = new BasicDBObject();
    value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
    update(this._systemDB, "activities", query, value);

    // new value for date_execution - 2nd upd
    value = new BasicDBObject();
    value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
    update(this._systemDB, "activities", query, value);

If I try to do this:

    BasicDBObject value = new BasicDBObject();
    value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
    value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
    or = update(this._systemDB, "activities", query, value);

just the 2nd set will be applied.

Is there any way do avoid the double execution and apply the update with just one call?

2 Answers 2

1

Basic rule of "hash/map" objects is that you can only have one key. It's the "highlander" rule ( "There can be only one" ) applied in general reason. So just apply differently:

BasicDBObject value = new BasicDBObject();
value.put("$set",
    new BasicDBObject("transactions.$.date_execution",new Date())
        .add( new BasicDBObject("transactions.$.result",m_OR.getDocument() )
);

So basically "both" field arguments are part of the "$set" statement as in the serialized form:

{
   "$set": {
       "transactions.$.date_execution": new Date(),
       "transactions.$.result": m_Or.getDocument()
   }
}

Which is basically what you want in the end.

Sign up to request clarification or add additional context in comments.

Comments

0

Your suggestion was right, just had to fix a little the syntax this way:

BasicDBObject value = new BasicDBObject();
value.put("$set",
        new BasicDBObject("transactions.$.date_execution",new Date())
        .append("transactions.$.result",m_OR.getDocument())
);

This worked perfectly ;)

Thanks! Samuel

Comments

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.