JD

10 November 2014

Lookup lists (using MongoDB)

Darb.io Lookups (in MongoDB)

An example of how to do lookups in MongoDB, without persisting the data or having to maintain relationships etc. in your services.

Background

In an object model we often want to specify a domain type (as in ‘domain classification’, not object type) to an object.

Example

Take the example of an Organization. In our domain, Organizations have a name, and an organization type (classification). The organization types available are:

  • Private Enterprise
  • Government
  • Not for profit

Historically, this relationship would probably have been either:

  • Maintained in a lookup table
  • Provided as an enumeration

The problem

Each method has drawbacks:

Enumeration

  • An enumeration is a very basic string representation - what if I need more than a basic string?
  • Attributes on enumerations can work, but are a messy way to persist meta data.

Lookup table

  • An interface is required to maintain the list (CRUD an organization type)
  • You need to either:
    • Maintain a relationship on an object. In a RDMS world, this is easy, but what if you are using NoSQL? Relationships in NoSQL are not wunderbar.
    • Maintain the object inside the NoSQL entity. This can lead to problems with data being out of sync.

The solution

Background

When I’m modelling (domain model, not catwalk… I gave that up) I like to try and keep as much of the domain model in POCO form.

Relationships are mapped as references to other types, as per this pseudocode, which represents an prganization with an array of employees, and an organization type:

class organization {
  string name;
  organization_type type;
  person[] employees;
}

class organization_type {
  string identifier;
  string description;
}

class person {
  string name;
}

I also like to follow the following general architecture:

  • Core (Interfaces, Domain model) (references only system)
  • Persistence (Implementation of a repository, Entities) (references core)
  • Application (references core and persistence)

The nitty gritty

The solution in this repository allows us to persist the multiple organization type domain objects to a single organization entity in the persistence layer, with a type identifier on it.

Each individual organization type domain object is mapped using AutoMapper to the OrganizationTypeEntity type in the database. The properties on the type are marked as BsonIgnore, which means the properties are not persisted to the datastore.

RoboMongo view

When an object is rehydrated from the database, the type mapping set up in the repository maps the object back to the specified type from the doamin model:

Application view

This allows us to add (and remove, with care) organization types from our code base, without having to maintain a lookup table. These lookup items can be edited and changed by editing the source code.

This pattern also ensures that there isn’t needless replication between documents in the database, helping to keep the document size low and keep queries lean and efficient.


← Back