Bitwise update operator with $setOnInsert

26 views
Skip to first unread message

Nilesh Akhade

unread,
Aug 16, 2017, 4:46:07 AM8/16/17
to mongodb-user
Hello everyone,

Here I am unsetting the flag, for which part of record (info_a, info_b, ...) is updated.

Flag logic:

1 1 1 1
d c b a <-- info parts

If info_a is received then we unset flag at position 0. Similarly for b, c and d.

db.collection.update(
   { "_id": "1", "flag": { $bitsAllSet: 1 } },
   { 
        $set: { "info_a": "XYZ" },
        $bit: { "flag": { and: NumberInt(14) /*Negation of 1*/ } },
        $setOnInsert: { "source": "feed", "flag": NumberInt(14) }
    },
   { upsert: true }
)

WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16836,
                "errmsg" : "Cannot update 'flag' and 'flag' at the same time"
        }
})

Expected:
If exists then and existing flag with 14
Else insert with flag: 14

Kevin Adistambha

unread,
Sep 5, 2017, 1:09:27 AM9/5/17
to mongodb-user

Hi Nilesh

It’s been some time since you posted this question. Have you found a solution in the meantime?

The error message you observe is because you’re trying to set the flag field twice in a single statement. Having said that, is there a specific reason why you need to use a bit field in your document? Please note that currently MongoDB supports the $bit operation on either 32-bit or 64-bit integer fields (see $bit). Alternatively, is it possible in your design to enumerate the “flags” into a sub-document or an array instead? For example:

{... info: {a: 0, b: 1, c: 1, d: 1} ...}

or using boolean values:

{... info: {a: false, b: true, c: true, d: true} ...}

Expected:
If exists then and existing flag with 14
Else insert with flag: 14

The update method doesn’t currently support conditionals in its operation. If you need to implement some logic in your update, you may find it easier to implement it in your application code instead.

Best regards,
Kevin

Nilesh Akhade

unread,
Sep 5, 2017, 12:50:01 PM9/5/17
to mongodb-user
Thanks Kevin,
you’re trying to set the flag field twice in a single statement   It is twice, but once in $setOnInsert, which should never collide with $bit.. In other words flag is once in insert and once in update($bit).

The update method doesn’t currently support conditionals in its operation   As per $setOnInsert docs update operation $setOnInsert executes if doc not exists(upsert). So I expected $bit part should not execute in case of $setOnInsert.

I was wrong in understanding $setOnInsert.

The problem is resolved by adding bit operations in application code. :)

Thanks again!!
Reply all
Reply to author
Forward
0 new messages