The MongoDB Java Driver provides low-level access to MongoDB. Spring Data MongoDB builds on top of it, but understanding the native driver helps with complex operations.

Native Driver Setup

  <dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.11.1</version>
</dependency>
  
  MongoClient client = MongoClients.create("mongodb://localhost:27017");
MongoDatabase db = client.getDatabase("myapp");
MongoCollection<Document> users = db.getCollection("users");
  

CRUD Operations

  // Insert
Document user = new Document("name", "Alice")
    .append("email", "[email protected]")
    .append("createdAt", Instant.now());
users.insertOne(user);

// Find
Document found = users.find(Filters.eq("email", "[email protected]")).first();

// Find with projection
users.find(Filters.eq("active", true))
    .projection(Projections.include("name", "email"))
    .sort(Sorts.descending("createdAt"))
    .limit(10)
    .into(new ArrayList<>());

// Update
users.updateOne(
    Filters.eq("_id", userId),
    Updates.combine(
        Updates.set("name", "Alice Smith"),
        Updates.currentDate("updatedAt")
    )
);

// Delete
users.deleteOne(Filters.eq("_id", userId));
  

Filters and Queries

  // Comparison
Filters.gt("price", 100)
Filters.lte("quantity", 0)
Filters.in("category", "electronics", "books")

// Logical
Filters.and(
    Filters.eq("active", true),
    Filters.gt("price", 50)
)
Filters.or(Filters.eq("status", "pending"), Filters.eq("status", "processing"))

// Text search
Filters.text("java programming")

// Array
Filters.all("tags", "java", "spring")
Filters.elemMatch("reviews", Filters.gt("rating", 4))
  

Aggregation Pipeline

  List<Bson> pipeline = List.of(
    Aggregates.match(Filters.eq("category", "electronics")),
    Aggregates.group("$brand",
        Accumulators.sum("totalSold", "$quantity"),
        Accumulators.avg("avgPrice", "$price")
    ),
    Aggregates.sort(Sorts.descending("totalSold")),
    Aggregates.limit(10)
);

users.aggregate(pipeline, Document.class).into(new ArrayList<>());
  

Indexes

  // Single field
users.createIndex(Indexes.ascending("email"), new IndexOptions().unique(true));

// Compound
users.createIndex(Indexes.compoundIndex(
    Indexes.ascending("category"),
    Indexes.descending("createdAt")
));

// Text index
users.createIndex(Indexes.text("name", "description"));
  

POJO Mapping

  CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
    MongoClientSettings.getDefaultCodecRegistry(),
    CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);

MongoClientSettings settings = MongoClientSettings.builder()
    .applyConnectionString(new ConnectionString("mongodb://localhost:27017"))
    .codecRegistry(pojoCodecRegistry)
    .build();

MongoClient client = MongoClients.create(settings);
MongoCollection<User> users = client.getDatabase("myapp")
    .getCollection("users", User.class);

users.insertOne(new User("Alice", "[email protected]"));
User found = users.find(Filters.eq("email", "[email protected]")).first();
  

For Spring applications, prefer Spring Data MongoDB:

  @Document("users")
public class User {
    @Id private String id;
    private String name;
    private String email;
}

public interface UserRepository extends MongoRepository<User, String> {
    Optional<User> findByEmail(String email);
    List<User> findByNameContaining(String name);
}
  

Best Practices

  • Use Spring Data MongoDB for standard CRUD in Spring applications
  • Use native driver for complex aggregations and bulk operations
  • Create indexes for all frequently queried fields
  • Use POJO codec for type-safe document mapping
  • Design documents around read patterns — embed related data when read together