pharo-nosql / mongotalk

A Pharo driver for MongoDB
MIT License
19 stars 13 forks source link

Using OrderedDictionary instead of Dictionary #105

Open ErikOnBike opened 2 years ago

ErikOnBike commented 2 years ago

MongoDB uses BSON for storing its documents [1]. BSON in contrast with JSON has ordered key/value pairs [2]. I think this means we should use OrderedDictionary for our documents (instead of Dictionary). This is also mentioned in #61 and does not only refer to the data we store, but also things like commands and the sort order which is specified by a document [3] when querying. For example, the current MongoQuery implementation uses a Dictionary which could give incorrect results (even if provided as an OrderedDictionary it still replaces it with a Dictionary [4]):

MongoQuery >> #order: anArrayOfAssociation
    order := anArrayOfAssociation asDictionary.

Any thoughts on how to tackle this?

We could simply replace all existing references to Dictionary (or #asDictionary) with the OrderedDictionary within MongoTalk, but I'm not sure if it would break existing code (elsewhere). From the Voyage-Mongo extension there is also reference to Dictionary which might need to be replaced as well. Maybe in other places too.

Another solution would be to add #asDictionary as an extension method to OrderedDictionary (and simply answer self) to prevent a correctly provided document from being changed. Then it is the user's responsibility to provide the correct documents. But would that break other (non Mongo-related) behaviour?

The 'in-between' solution could be to implement an #asBSONDocument behaviour and use it consistently within MongoTalk. Allowing both Dictionary and Array (of Associations) instances to be converted to an OrderedDictionary instance.

Interested in your thoughts about this.

[1] https://docs.mongodb.com/manual/core/document/ [2] https://bsonspec.org/spec.html (see first paragraph BSON is a binary format in which zero or more ordered key/value pairs are stored as a single entity.) [3] https://docs.mongodb.com/manual/reference/method/cursor.sort/ [4] It is not fully clear whether #order: expects an Array or a Dictionary, since the following method (one of two users of the setter) seems to specify it is a Dictionary:

MongoCollection >> #select: aDictionary limit: limit offset: offset order: orderDictionary flags: flags
    ^ self query: [:query |
        query
            where: aDictionary;
            limit: limit; 
            offset: offset; 
            order: orderDictionary;
            flags: flags ]