Spring Data MongoDB — a Spring module for working with MongoDB (NoSQL, document database).
Simple analogy: MongoDB is like a cabinet with folders. In each folder (collection) are documents (JSON), each with its own set of fields. No fixed structure (schema) is needed. Imagine a filing cabinet where each folder can hold documents of completely different formats — one might be a receipt, another a photo, another a letter. This flexibility is MongoDB's core strength.
Why it matters: MongoDB is ideal when your data model evolves rapidly, when you have deeply nested documents (like product catalogs with varying attributes), or when you need horizontal scalability through sharding. Spring Data MongoDB makes working with it as seamless as JPA makes working with relational databases.
Connection:
1# application.yml2spring:3 data:4 mongodb:5 uri: mongodb://localhost:27017/mydb6 auto-index-creation: true
Document:
1@Document(collection = "users")2@Indexed(compoundIndex = @CompoundIndex(name = "email_status",3 def = "{'email': 1, 'status': 1}"))4public class User {5 @Id6 private String id;7 private String name;8 private String email;9 @Field("created_at")10 private LocalDateTime createdAt;11 @DBRef // Reference to another document12 private Role role;13 @Version14 private Long version; // Optimistic locking15}
Repository:
1public interface UserRepository extends MongoRepository<User, String> {2 Optional<User> findByEmail(String email);3 List<User> findByNameContainingIgnoreCase(String name);4 @Query("{'age': {'$gte': ?0, '$lte': ?1}}")5 List<User> findByAgeRange(int min, int max);6 List<User> findByRoleName(String roleName); // Nested document78 @Aggregation(pipeline = "{9 "$group": {"_id": "$status", "count": {"$sum": 1}}10 }")11 List<Document> countByStatus();12}
MongoTemplate (low-level):
1@Service2public class UserService {3 @Autowired private MongoTemplate mongoTemplate;45 public List<User> findActiveUsers() {6 Query query = new Query();7 query.addCriteria(Criteria.where("status").is("ACTIVE"));8 query.with(Sort.by(Sort.Direction.DESC, "createdAt"));9 query.limit(10);10 return mongoTemplate.find(query, User.class);11 }1213 public void upsert(User user) {14 Query query = new Query(Criteria.where("email").is(user.getEmail()));15 Update update = new Update()16 .set("name", user.getName())17 .set("updatedAt", LocalDateTime.now());18 mongoTemplate.upsert(query, update, User.class);19 }20}
Common mistakes:
@DBRef — each lazy-loaded reference triggers a separate query. Use @DBRef(lazy = false) or fetch eagerly.When MongoDB is better than PostgreSQL: