Using MongoDB with Spring Data MongoDB

From Luis Gallego Hurtado - Not Another IT guy
Jump to: navigation, search


We will discuss about non-reactive programming with Spring Data MongoDB

Project Setup

Setup the Spring boot project:

  1. Add the maven dependency org.springframework.boot:spring-boot-starter-data-mongodb
  2. Specify the spring.data.mongodb.uri

Manipulating MongodDB data

Spring Data MongoDB offers different abstraction levels, allowing you to store/retrieve data in several ways, depending on the level of abstraction.

Using Mapped Entities

You can annotating your persistence entities with annotations and then, just performing CRUD operations over them.

This mechanism uses the Java-MongoDB mapping mechanism, applying appropriate conversions for every value to send/retrieve.

Using a MongoOperations implementation like MongoTemplate

Interface org.springframework.data.mongodb.core.MongoOperation and its implementation org.springframework.data.mongodb.core.MongoTemplate, expose methods for retrieving/updating data into MongoDB.

Some of the methods retrieve the entity class to map the data with/to, in which case, the library apply the appropriate conversions.

Some other methods work in a lower abstraction level, executing commands over the MongoDB API, so no conversiosn are applied since the receive a json string, or one or several instances of org.bson.Document class.

Executing Aggregation Pipeline with MongoOperations

Interface org.springframework.data.mongodb.core.MongoOperation and its implementation org.springframework.data.mongodb.core.MongoTemplate, expose aggregate method that runs an aggregation pipeline over MongoDB and returns an org.springframework.data.mongodb.core.aggregation.AggregationResults object.

Note that AggregationResults object is an iterable that returns both the mapped results and and raw results (unmapped document) on every iteration.

It is important to remark that on building the org.springframework.data.mongodb.core.aggregation.Aggregation, the usage of the option allowDiskUsse with true value is recommended so MongoDb servers are not limited by the memory.

Useful Aggregation Operations

  • MatchOperation
  • ProjectionOperation
  • SortOperation
  • FacetOperation
  • UnwindOperation

Custom Aggregation Operations and Expressions

You can build any extras org.springframework.data.mongodb.core.aggregation.AggregationOperation, by implementing such interface, and overriding the following methods:

  • getOperator should return the MongoDB operator of such operation.
  • toDocument should return the instance of org.bson.Document that represents the object with paramenters of such operator.

Please, note that there are 2 interfaces for operations exposing and consuming fields: org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation and org.springframework.data.mongodb.core.aggregation.FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation.

In case of requiring new expressions, that can be done by creating new implementations of org.springframework.data.mongodb.core.aggregation.AggregationExpression interface, implementing the toDocument method that returns the org.bson.Document instance for current expression, given an org.springframework.data.mongodb.core.aggregation.AggregationOperationContext.

Logging

I would recommend on non productive environments to set the logger of org.springframework.data.mongodb.core.MongoTemplate to debug.

Add Spring Custom converters

Setting Up Spring Custom Converters

In order to add converters, we just need to create a org.springframework.data.mongodb.core.convert.MongoCustomConversions bean with the list of converters to use.

Remember to implement safety checks in the converters so they return null when value to convert is null.

I also suggest to register the converters as @org.springframework.stereotype.Compontent, and use the @org.springframeworkg.data.convert.ReadingConverter and @org.springframeworkg.data.convert.WritingConverter annotations.

Java 8 Date API converters

Since the Spring Data MongoDB works with java.util.Date, I recommend to add custom Spring converters for converting from/to Java 8 API dates, using a unique ZoneOffset like ZoneOffset.UTC.

Retrieving JSON value

When retrieved value is an Object, you can map it to String property so JSON value is conveniently stored. When retrieved value is an Array, you need a converter that converts any List<?> to a String, and retrieve there the JSON string representation of such List.


You can create a converter that converts any List<?> to