SSPkrolik / nimongo

Pure Nim lang MongoDB driver
http://sspkrolik.github.io/nimongo
MIT License
101 stars 20 forks source link

For upcoming PR #1: adding 'insertMany' method to support OP_INSERT and returned OIDs #45

Closed JohnAD closed 6 years ago

JohnAD commented 6 years ago

Currently, nimongo uses the "$cmd" virtual collection for most of it's operations, which is just fine in general.

But that does have one fairly significant downside: when issuing the insert command, the server only reports success or failure. It does not report the "_id"(s) that the server just assigned. Details:

https://docs.mongodb.com/manual/reference/command/insert/#dbcmd.insert

So, if I create a new document; I either need to preemptively assign a psuedo-unique OID, or, I need to ensure that there is some other means of locating the document I just created (since I never got the _id). The is important if I wish to then add a foreign reference in another document, for example.

Alternatively, if one issues the general purpose insertMany command directly to the collection (OP_INSERT instead of OP_QUERY), one automatically gets oids back in the returned BSON:

https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#insertmany-examples

Within the next day or so, I plan to start a WIP PR that adds protocol support for OP_INSERT to the nimongo library. InsertMany return a BSON document containing the _ids returned by the server rather than a StatusReply.

JohnAD commented 6 years ago

erm...never mind.

I got about 50% done on this; and realized that OP_INSERT doesn't actually return _id. Nothing in the wire protocol does. It is merely the shell that does it by pre-loading _ids if the _ids are missing. MongoDB's own documentation does not actually mention this anywhere. You have to pick it up by inference; which is something a driver-writer would eventually do. :)

I confirmed this my going to one of MongoDB's official libraries: pymongo. And that library does that very thing. On an insert_one, it detects if the _id is missing, and if so, generates one locally using ObjectID() and adds it to the document; that way the new ids are know prior to insertion.

(if nothing else, I just got a quick lesson as to how the MongoDB server protocol works.)

So, I will go that route also. Does the following sound good to everyone:

ref: https://github.com/mongodb/mongo-python-driver/blob/507f954ed4f5778b2cc2d34fd57ff5525f4d2be0/pymongo/operations.py