Docs Menu
Docs Home
/ / /
Java Sync Driver
/ /

Single-Collection Design

Single-collection designs in MongoDB offer a flexible and efficient way to model data by storing related documents in a single collection. This approach can simplify data access patterns and reduce the need for complex joins, which are not natively supported in MongoDB.

Spring Data MongoDB bridges the gap between MongoDB’s flexible document model and Java’s strongly typed class system, making single-collection designs easier to implement, manage, and scale. In this guide you can learn how to implement single-collection designs in Java applications using Spring Data MongoDB.

A single-collection design stores multiple related entities in a single MongoDB collection. Each document in the collection can represent a different entity type, distinguished by a discriminator field. This design is particularly useful when entities share a common set of fields and are frequently accessed together.

Consider an e-commerce platform where customers, sellers, and administrators are stored in the same collection. Each document includes a userType field to differentiate between the entity types:

{
"_id": ObjectId("64b8c123abc123"),
"userType": "customer",
"name": "Alice",
"email": "alice@example.com",
"orders": [{"orderId": 1, "total": 100}]
}
{
"_id": ObjectId("64b8c456abc456"),
"userType": "seller",
"name": "Bob's Store",
"email": "bob@example.com",
"products": [{"productId": 101, "price": 20}]
}
{
"_id": ObjectId("64b8c789abc789"),
"userType": "admin",
"name": "Charlie",
"email": "charlie@example.com",
"permissions": ["manageUsers", "manageOrders"]
}

This structure allows for efficient querying and updates, since all related data is contained in a single collection.

Include the following dependency in your pom.xml to integrate Spring Data MongoDB:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

In your application.properties:

spring.data.mongodb.uri=mongodb://localhost:27017/yourDatabase

Or define a custom configuration class:

@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {
@Override
protected String getDatabaseName() {
return "yourDatabase";
}
@Override
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/yourDatabase");
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
}

Create a base class for common fields:

public abstract class User {
@Id
private String id;
private String name;
private String email;
private String userType;
}

Define subclasses for each user type:

@Document(collection = "users")
public class Customer extends User {
private List<Order> orders;
}
@Document(collection = "users")
public class Seller extends User {
private List<Product> products;
}
@Document(collection = "users")
public class Admin extends User {
private List<String> permissions;
}

Create a repository interface for the User entity:

public interface UserRepository extends MongoRepository<User, String> {
List<User> findByUserType(String userType);
}

Implement a service class to handle business logic:

@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUsersByType(String userType) {
return userRepository.findByUserType(userType);
}
}

In your test class:

@SpringBootTest
public class UserServiceTests {
@Autowired
private UserService userService;
@Test
public void testGetUsersByType() {
List<User> customers = userService.getUsersByType("customer");
assertNotNull(customers);
assertFalse(customers.isEmpty());
}
}
  • Simplified Data Access: All related data is stored in a single collection, reducing the need for joins.

  • Improved Performance: Fewer collections means fewer indexes to manage and faster queries in many use cases.

  • Flexible Schema: MongoDB’s schema-less nature enables storing different structures in the same collection.

  • Easy Polymorphic Queries: Query across all user types or filter by type using simple query parameters.

Single-collection designs are a powerful modeling pattern in MongoDB that can simplify your application's persistence layer. Using Spring Data MongoDB in Java, you can implement this pattern with minimal configuration while maintaining strong typing and repository support.

For more advanced scenarios—including handling polymorphism, aggregations, and validation—consider diving deeper into the Spring Data MongoDB documentation and the MongoDB schema design patterns.

Back

Spring Data Integration

On this page