Introducing Doctrine MongoDB ODM 1.2

With the release of Doctrine MongoDB ODM 1.2, we’ve introduced several new features. I want to highlight some of them in this blog post and give an outlook on future development of MongoDB ODM.

Aggregation builder

With aggregation builder, we’re giving you a tool to create aggregation pipeline queries similar to how you create other queries in ODM. The builder takes into account mapping information to convert field names and types and also allows you to receive your results as mapped documents.

Previously, you had to run all aggregation pipeline queries through the collection object directly, receiving a list of arrays as result:

With the new aggregation builder, you can use a fluent builder interface and you don’t have to manually convert objects to their MongoDB types. To get result objects from an aggregation pipeline query, first create a QueryResultDocument to hold the aggregated data:

You may note that the query result document does not have an identifier. Instead, we specify that the database name for our user reference is _id. This allows us to have a reference to a different object as identifier. The user reference will be returned as proxy object and only is initialized when first accessing any property of it.

Now you can create your aggregation pipeline query and use the hydrate method to get objects as result:

The aggregation builder supports all aggregation pipeline stages present in MongoDB 3.4, including $lookup and $graphLookup. When looking up references, you can simply specify the name of the reference to look up and the pipeline stage will do the rest for you.

Due to a limitation in MongoDB, $lookup and $graphLookup can’t be used with references that are stored as DBRef objects, only with references stored as id or the new ref type.

DBRef replacement for storing references

As mentioned above, MongoDB does not support looking up references from DBRef objects. This is due to the field names in DBRef which contain a leading dollar sign. Storing your references as id works, but makes them incompatible with discriminators. To solve this problem, we introduced the new ref storage type for references. It works like a DBRef object, but only stores the identifier of the referenced object and any discriminator field if present in the mapping. This new type is opt-in, so as long as you’re not using references in aggregation pipelines, you can happily keep using DBRef for storing your references. To use this new storage type, simply specify a value of ref for storeAs in your reference mapping:

Using primers for inverse references

Reference priming helps you avoid n+1 problems by initializing proxy objects of the same type at once, resulting in one query instead of one query for each proxy. You could enable reference priming in the query builder:

In inverse references, the only way to prime other references was to map the inverse reference using a repositoryMethod and build the query manually. To avoid this code overhead, you can now specify which fields to prime in an inverse reference with mappedBy:

Note that for inverse references mapped with repositoryMethod, the primers in the mapping take precedence and override any primers that might have been set on the query already.

Future development

With 1.2.0 released, development now focuses on replacing the legacy MongoDB driver (ext-mongo) with its new counterpart, ext-mongodb. This also allows you to run ODM on PHP 7+ without the need of polyfill libraries like mongo-php-adapter. We hope to release a first beta version of ODM 2.0 before the end of the year, with a final release no later than the first quarter of 2018 (no, we’re not going to do another 5-year beta phase).

We’ve already started deprecating features like slaveOkay, requireIndexes and much more in 1.2 and will make several more deprecations as we work on 2.0. Since deprecations can only be introduced in minor releases, we will release 1.3.0 at about the same time as the first beta for ODM 2.0. This version will deprecate all features to be removed in 2.0, and we’ll also try to add a forward compatibility layer to 2.0 where possible. It will also be the last release compatible with PHP 5.6, and we’ll continue to support it for 6 months after the release of ODM 2.0.

Doctrine coordinator and MongoDB ODM maintainer. I break stuff so you don’t have to. Lead Engineer @mongodb — join me in making databases more fun to use.

Doctrine coordinator and MongoDB ODM maintainer. I break stuff so you don’t have to. Lead Engineer @mongodb — join me in making databases more fun to use.