A cautionary tale - mgo asserts
James Tunnicliffe
james.tunnicliffe at canonical.com
Thu Jun 9 09:15:58 UTC 2016
OK, how about this as an argument (that I am not necessarily saying is
right, but we want a well justified change): Mongo changed in the
past. Ordering isn't important to us, only key: value pairs. Given
these, we can happily say that being explicitly unordered on the Juju
level or even the mgo/txn level of the software stack guarantees only
what we are interested in and defends us against Mongo becoming
unordered in the future by accident or design.
On Thu, Jun 9, 2016 at 10:10 AM, roger peppe <roger.peppe at canonical.com> wrote:
> 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