Is it possible to store multiple types of Objects into 1 mongodb collection?

Marcel picture Marcel · Mar 5, 2014 · Viewed 9.3k times · Source

using document oriënted database mongodb and the Object Document Mapper (ODM) morphia

Lets say we have 3 different classes; Object, Category and Action.
These object are all stored in the collections; objects, categories and actions.

Category and Action are references of Object

@Entity("objects")
public class Object {

    @Id
    @Property("id")
    private ObjectId id;

    @Reference
    private Category category;
    private Action action;
    ...
}

@Entity("categories")
public class Category {

    @Id
    public String categoryTLA;
    public String categoryName;
    ...
}

@Entity("actions")
public class Action implements BaseEntity {

    @Id
    public String action;
    public int accesLevel;
    ...
}

The documents with the current implementation are stored like:

  • Mongo (Server/location)
    • store (database)
      • objects (collection)
        • object (document)
        • object
        • object
      • categories
        • categorie
        • categorie
        • categorie
      • actions
        • action
        • action
        • action

Is it possible to store 2 different Objects, in this case Category and Action, in one collection, like shown in the next example? Both with their own identification!

  • Mongo
    • store
      • objects
        • object
        • object
        • object
      • settings
        • categorie
        • categorie
        • categorie
        • action
        • action
        • action

Answer

WiredPrairie picture WiredPrairie · Mar 5, 2014

Absolutely, it's possible to store multiple types of documents in a single collection. In fact, that's one of the strengths of a document oriented database like Mongo. However, you may not want to combine them without considering some issues (positive and negative):

  1. You can't do cross-collection or document SQL-like JOINs. So, having documents in one or more collection won't change that behavior.
  2. You can use aggregation only in a single collection, so you may be able to perform some aggregation style queries more conveniently if a collection has multiple document types rather than split across collections (both the aggregation framework and Map-Reduce operate only on a single collection at a time).
  3. In order to deserialize a document into an object in Morphia, you'll need to know what type a given document represents. You may need to add a field to the document indicating the type, unless there are other ways that can safely represent the type of document so that the deserialization process works correctly. An Action can't be a Category for example. If you did the equivalent of FindAll and there were multiple document types, unless the deserializer can evaluate the document structure before deserialization starts, your code may not work as desired.
  4. It's likely that you'll need to index various properties of your documents/Objects. If you index based on document types (say Action has an index that is unqiue from Category, all documents inserted into the collection containing both will run through the indexer, for all indexes defined in the collection. That can impact performance depending on the nature of the indexes. This means that all documents in the collection will be indexed regardless of whether the index makes sense. This is often a compelling reason to not combine multiple document types that do not share common indexing traits.

Unless you need to do specific types of queries that require all documents to be in a common collection, I'd likely leave them in separate collections, especially if you plan on using custom indexes for various document types/schemas.