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