A cautionary tale - mgo asserts
roger peppe
roger.peppe at canonical.com
Thu Jun 9 09:10:41 UTC 2016
In fact it seems that MongoDB (as of version 2.6) *does* make
some guarantees about field order:
>From https://docs.mongodb.com/master/release-notes/2.6/#insert-and-update-improvements:
: MongoDB preserves the order of the document fields following write
operations except for the following cases:
:
: - The _id field is always the first field in the document.
: - Updates that include renaming of field names may result in the
reordering of fields in the document.
So the situation isn't perhaps as bad as made out in the blog post I
linked to earlier.
cheers,
rog.
On 9 June 2016 at 09:58, James Tunnicliffe
<james.tunnicliffe at canonical.com> wrote:
> Surely we want to remove any ordering from the txn logic if Mongo
> makes no guarantees about keeping ordering? Being explicitly unordered
> at both ends seems right.
>
> James
>
> On Thu, Jun 9, 2016 at 8:35 AM, roger peppe <roger.peppe at canonical.com> wrote:
>> On 9 June 2016 at 01:20, Menno Smits <menno.smits at canonical.com> wrote:
>>> On 8 June 2016 at 22:36, John Meinel <john at arbash-meinel.com> wrote:
>>>>>
>>>>> ...
>>>>
>>>>
>>>>>
>>>>>
>>>>> ops := []txn.Op{{
>>>>> C: "collection",
>>>>> Id: ...,
>>>>> Assert: bson.M{
>>>>> "some-field.A": "foo",
>>>>> "some-field.B": 99,
>>>>> },
>>>>> Update: ...
>>>>> }
>>>>>
>>>>>> ...
>>>>
>>>>
>>>> If loading into a bson.M is the problem, wouldn't using a bson.M to start
>>>> with also be a problem?
>>>
>>>
>>> No this is fine. The assert above defines that each field should match the
>>> values given. Each field is checked separately - order doesn't matter.
>>>
>>> This would be a problem though:
>>>
>>> ops := []txn.Op{{
>>> C: "collection",
>>> Id: ...,
>>> Assert: bson.M{"some-field": bson.M{
>>> "A": "foo",
>>> "B": 99,
>>> },
>>> Update: ...
>>> }
>>>
>>>
>>> In this case, mgo is being asked to assert that some-field is an embedded
>>> document equal to a document defined by the bson.M{"A": "foo", "B": 99} map.
>>> This is what's happening now when you provide a struct value to compare
>>> against a field because the struct gets round-tripped through bson.M. That
>>> bson.M eventually gets converts to actual bson and sent to mongodb but you
>>> have no control of the field ordering that will ultimately be used.
>>
>> Actually, this *could* be OK (I thought it was, in fact) if the bson encoder
>> sorted map keys before encoding like the json encoder does. As
>> it doesn't, using bson.M is indeed definitely wrong there.
>>
>> This order-dependency of ostensibly order-independent objects really is an
>> unfortunate property of MongoDB.
>>
>> --
>> Juju-dev mailing list
>> Juju-dev at lists.ubuntu.com
>> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/juju-dev
More information about the Juju-dev
mailing list