I am using MongoDB in a project, where relationships between collections are created via referencing a unique document ID of a special BSON ObjectID type.

So I can have a School document like this:

{ name : 'Country School', _id : ObjectId("aaaaaaaaaaaaaa") }

Also, I can have a Subject document like this:

{ name: 'Maths', _id : ObjectId("yyyyyyyyyyyyy") }

And then Teacher document in Teachers collection:

{ name "Mr Brown", school: ObjectID("aaaaaaaaaaaaaa"), subject:  ObjectId("yyyyyyyyyyyyy") }

The problems start when I need to update Teacher document in View:

  • How should the controller return Teacher object to the View?

Clearly, to facilitate a layer of abstraction from the DB I need to convert this ObjectID into a string. It becomes a bit of a mess when Teacher has many properties that are essentially ObjectIDs - each time I go back and forth between View and Controller I end up needing bespoke code to convert each of these properties to ObjectID and back to string.

When going from "Controller" -> "View" I can easily check which fields have type 'ObjectId' and convert them to string. But when I am going "View" -> "Controller", is the only solution to hard-code which fields should become ObjectId? Maybe somehow include a reference to the type of the field in the field name, i.e. if file name is 'school_objectid' - convert it.

Is there an elegant solution to this problem?

  • Does the mongo objectid type have a toString() function?
    – JeffO
    Mar 17, 2017 at 19:26
  • Yes, it has. My issue lies in how the software converts fields to strings and then figures out which ones to convert back to ObjectID. Maybe there is some special custom object cast design pattern that I could use?
    – Tony Sepia
    Mar 17, 2017 at 19:27
  • ORM's have solved this for relational databases, maybe there's something out there for Mongo.
    – JeffO
    Mar 22, 2017 at 14:38
  • Mongo is not supposed to be relational that's it.
    – Laiv
    Jan 17, 2018 at 7:23

2 Answers 2


Maybe you should consider not referencing the object ID in your code at all?

But the root of your problem is, you seem to be trying to use MongoDB as if it is a relational database.

In mongo, your entities are more or less supposed to stand alone.

Also, from your application, you should be looking things up with their natural key (or at least an application layer key, perhaps a guid)... I hope no one takes this suggestion as being against surrogate keys, nothing is further from a the truth. Surrogate keys are great, but even better when used in combination with natural keys.

  • Thank you for taking time to answer. My question isn't about Mongo. Just imagine a situation where you are reading a type from the DB, which isn't JSON-compatible. How would it travel from your Model, through the Controller, to the View, and then back? Where would you perform the conversion? At what stage? That is the question
    – Tony Sepia
    Jul 20, 2017 at 21:03
  • The problem is that you are having your view work directly with data, this will cause all sorts of problems. Your controller should be calling a repository, which saves/reads a CONCEPTUAL entity to/from the DB. The controller than translates the conceptual entity to a view model. Often, the view model will look very similar, if not the same as a conceptual model/entity; this is not a violation of DRY, these classes serve totally different functions, and their similarity is a coincidence. Jul 21, 2017 at 14:34

The best solution I could arrive at after a little bit of research is to create class definitions for objects that are essentially returned from the database.

  • add two constructors for them: one taking in entity that database driver returns, and one that takes in JSON returned by the web front-end.
  • Then add a method that returns an instance of the object with all BSON ID fields as strings (for use in the web front-end), and one that returns them as they are (of type ObjectID) to use with the DB driver.

It would be interesting to see what approach would experienced software architects employ

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.