Problem Statement/Rationale
A collection named "foo.bar" is perfectly valid. However in compass DBRef would display it as
DBRef('bar', ObjectId('6a73061f8f257c0343126b85'), 'foo')
Expected
DBRef('foo.bar', ObjectId('6a73061f8f257c0343126b85'))
Steps to Reproduce
Env: Python 3 python -m pip install pymongo
from pymongo import MongoClient from bson import DBRef, ObjectId from bson.codec_options import CodecOptions from bson.raw_bson import RawBSONDocument import bson client = MongoClient("mongodb://localhost:27017/") db = client["testdb"] db.drop_collection("foo.bar") db.drop_collection("baz") # 1. Insert a document into a collection whose name itself contains a dot. inserted = db["foo.bar"].insert_one({"name": "hello"}) target_id = inserted.inserted_id print("Inserted into 'foo.bar':", target_id) # 2. Build a DBRef pointing at that collection, using ONLY collection + id # (no database arg) -- this is the correct way to reference it. ref = DBRef("foo.bar", target_id) print("Constructed DBRef:", ref) print(" ref.collection:", ref.collection) print(" ref.database:", ref.database) # 3. Store the DBRef in another document and read it back. db["baz"].insert_one({"ref": ref}) readback = db["baz"].find_one() print("Read back via pymongo:", readback) print(" readback['ref'].collection:", readback["ref"].collection) print(" readback['ref'].database:", readback["ref"].database) # 4. Inspect the raw BSON bytes actually stored on disk, bypassing # pymongo's automatic DBRef decoding, to prove nothing got split. raw_coll = db.get_collection("baz", codec_options=CodecOptions(document_class=RawBSONDocument)) raw_doc = raw_coll.find_one() print("Raw BSON bytes:", raw_doc.raw) print("Decoded raw BSON:", bson.decode(raw_doc.raw))
Output
Inserted into 'foo.bar': 6a74f7612f58af1a5a376b87 Constructed DBRef: DBRef('foo.bar', ObjectId('6a74f7612f58af1a5a376b87')) ref.collection: foo.bar ref.database: None Read back via pymongo: {'_id': ObjectId('6a74f7612f58af1a5a376b88'), 'ref': DBRef('foo.bar', ObjectId('6a74f7612f58af1a5a376b87'))} readback['ref'].collection: foo.bar readback['ref'].database: None Raw BSON bytes: b'C\x00\x00\x00\x07_id\x00jt\xf7a/X\xaf\x1aZ7k\x88\x03ref\x00(\x00\x00\x00\x02$ref\x00\x08\x00\x00\x00foo.bar\x00\x07$id\x00jt\xf7a/X\xaf\x1aZ7k\x87\x00\x00' Decoded raw BSON: {'_id': ObjectId('6a74f7612f58af1a5a376b88'), 'ref': DBRef('foo.bar', ObjectId('6a74f7612f58af1a5a376b87'))}
Expected Results

Actual Results


Additional Notes
This is only a display bug within Compass; at the DB level, it's stored as expected, as confirmed in the Python snippet.
DBRef('foo.bar', ObjectId('6a74f7612f58af1a5a376b87'))
Expected Behavior
As a js-bson user
I expect dbrefs to correctly refer to collection names featuring '.'
When creating a new DBref
Actual Behavior and Impact
- New instances of DBRef incorrectly pop namespaces (db name) off of the provided collection name, when it should be a literal
- Any user using the driver to store db refs for collection names with periods, as well as any user using compass or mongosh with existing DBref's fitting a valid format to their original intention, will see an incorrect db ref.
Dependencies
- Mongosh, compass and the driver will need to be updated to include the fix verison of js-bson
- Specifications repo needs to be updated with test cases that would have caught this issue
- https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/dbref.json
- the existing tests only use "collection" or "not-a-dbref" as collection names, so Node's split functionality is never tested against the spec
- open a DRIVERS ticket for the addition
- open a specifications PR to add the new tests
Risks/Unknowns
- Even though this is a fix (spec non compliance) it is technically breaking and users could be relying on this behaviour today
Acceptance Criteria
Implementation Requirements
- js-bson should treat collectionname ($ref in the spec) as a literal, and not try to mutate it
Testing Requirements
- tests should be updated to reflect this change
Documentation Requirements
- None needed, the existing API docs make no mention of any existing behaviour which contradicts spec
Follow Up Requirements
- js-bson fix version needs to be merged into compass & mongosh
- depends on
-
NODE-7866 Add period-separated dbref tests
-
- Backlog
-
- duplicates
-
NODE-3573 BSON library assumes $ref values containing a period are a full namespace
-
- Backlog
-
- related to
-
DRIVERS-3644 Add period-separated dbref tests
-
- Implementing
-