On 9 June 2016 at 10:15, James Tunnicliffe
<james.tunnicli...@canonical.com> wrote:
> 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.

That's a reasonable argument, but I see that 2.6 feature as a bug fix
that's very unlikely to regress.

Also, we must be very careful because the apparently equivalent
queries:

    bson.D{{"x", bson.D{{"a", "val1"}, {"b", "val2"}}}}
    bson.D{{"x.a", "val1"}, {"x.b", "val2"}}

are *not* identical.

The latter will match the document {x: {a: "val1", b: "val2", c: "val3"}} but
the former will not.

For example, in the fix for the bug that inspired this discussion,
https://github.com/juju/juju/commit/af94a93b633276550eb9cdc35714c910fe386354
the fixed code is not the same as the old code (this might
be a bug that's just been introduced).

To do it better, the fix could have done something like this:

    if current.Scope != "" {
        currentD = append(currentD, bson.D{{fieldName +
".networkscope", current.Scope}})
    } else {
        currentD = append(currentD, bson.D{{fieldName + ".networkscope", nil}})
    }

but even that's not necessarily sufficient because a future update
might add a field to state.address, and then the assert would succeed
even though the address is actually different from that asserted.

Because of this, I think that whole-document asserts are still useful and thus
it's probably worth fixing the mgo/txn logic.

BTW, the process of making a query that apparently queries the whole
document while actually using individual fields can be automated somewhat.
I did something similar with https://godoc.org/github.com/juju/mgoutil#AsUpdate
recently. This could save some of the legwork involved in making the bson.D
query.

  cheers,
    rog.

> On Thu, Jun 9, 2016 at 10:10 AM, roger peppe <roger.pe...@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.tunnicli...@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.pe...@canonical.com> 
>>> wrote:
>>>> On 9 June 2016 at 01:20, Menno Smits <menno.sm...@canonical.com> wrote:
>>>>> On 8 June 2016 at 22:36, John Meinel <j...@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@lists.ubuntu.com
>>>> Modify settings or unsubscribe at: 
>>>> https://lists.ubuntu.com/mailman/listinfo/juju-dev

-- 
Juju-dev mailing list
Juju-dev@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju-dev

Reply via email to