以下是基于Spring Boot操作MongoDB的完整示例大全,涵蓋增刪改查、聚合查詢、索引、事務等核心功能:
一、基礎CRUD操作
1. 環境配置
依賴配置(pom.xml)
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
核心配置(application.yml)
spring:data:mongodb:uri: mongodb://root:123456@192.168.3.11:27017/mydb?authSource=admin# 或分開配置host: 192.168.3.11port: 27017username: rootpassword: 123456authentication-database: admin
2. 實體類定義
@Data
@Document(collection = "users") // 指定集合名
public class User {@Idprivate String id;@Indexed(direction = IndexDirection.ASCENDING) // 單字段索引private String name;@TextIndexed // 全文索引private String email;private Integer age;private Date createDate;
}
3. Repository接口
public interface UserRepository extends MongoRepository<User, String> {// 方法名推導查詢List<User> findByName(String name);// 自定義JSON查詢@Query("{ 'age' : { $gt: ?0 } }")List<User> findByAgeGreaterThan(int age);
}
4. MongoTemplate操作
@Autowired
private MongoTemplate mongoTemplate;// 插入文檔
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setName("Alice");
mongoTemplate.insert(user); // 插入單個文檔// 查詢所有
List<User> users = mongoTemplate.findAll(User.class);// 根據ID查詢
User user = mongoTemplate.findById("1001", User.class);// 條件查詢
Query query = new Query();
query.eq("name", "Alice").gt("age", 20);
List<User> result = mongoTemplate.find(query, User.class);// 更新文檔
Update update = new Update();
update.set("name", "NewName").inc("age", 1);
mongoTemplate.updateFirst(Query.query(Criteria.where("id").is("1001")), update, User.class);// 刪除文檔
mongoTemplate.remove(Query.query(Criteria.where("id").is("1001")), User.class);
二、聚合查詢操作
1. 使用Aggregation API
// 聚合管道:匹配+分組統計
Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("age").gt(18)), // 過濾年齡>18Aggregation.group("department") // 按部門分組.count().as("total") // 統計人數.avg("salary").as("avgSalary"), // 計算平均工資Aggregation.sort(Sort.Direction.DESC, "total") // 按總人數降序排序
);// 執行聚合
AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, "users", Document.class);
2. 原生JSON聚合
// 直接使用JSON格式定義聚合管道
String pipeline = "[{ $match: { age: { $gt: 18 } } }, " +"{ $group: { _id: '$department', total: { $sum: 1 }, avgSalary: { $avg: '$salary' } } }, " +"{ $sort: { total: -1 } }]";AggregationResults<Document> results = mongoTemplate.aggregate(new BasicQuery(pipeline), "users", Document.class);
三、高級功能實現
1. 全文搜索
// 1. 創建文本索引
@TextIndexed
private String title;// 2. 使用TextCriteria查詢
public List<Note> searchNotes(String keyword) {TextCriteria criteria = TextCriteria.forDefaultLanguage().matching(keyword);Query query = new Query(criteria);return mongoTemplate.find(query, Note.class);
}
2. 事務管理
@Configuration
@EnableTransactionManagement
public class MongoConfig {@Beanpublic MongoTransactionManager transactionManager(MongoDatabaseFactory factory) {return new MongoTransactionManager(factory);}
}// 服務層使用@Transactional
@Service
public class TransferService {@Transactionalpublic void transferMoney(String fromId, String toId, double amount) {// 扣減轉出賬戶mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(fromId)), new Update().inc("balance", -amount), Account.class);// 增加轉入賬戶mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(toId)), new Update().inc("balance", amount), Account.class);}
}
3. 連接池調優
spring:data:mongodb:uri: mongodb://user:pass@host:27017/db?maxIdleTimeMS=300000&maxPoolSize=100&minPoolSize=10&maxWaitTimeMS=1000
四、性能優化技巧
1. 分頁查詢
// 使用Pageable實現分頁
Pageable pageable = PageRequest.of(0, 10, Sort.by("age").descending());
Query query = new Query().with(pageable);
List<User> users = mongoTemplate.find(query, User.class);
2. 復合索引
@CompoundIndexes({@CompoundIndex(name = "name_age_index", def = "{'name': 1, 'age': -1}")
})
public class User {}
3. 地理位置查詢
// 創建2D索引
@Field(store = true, indexDirection = Direction.GEO2D)
private Point location;// 查詢附近5公里內的用戶
Query query = new Query();
query.near("location", new GeoJsonPoint(116.4, 39.9)).maxDistance(5000);
List<User> nearbyUsers = mongoTemplate.find(query, User.class);
五、常見異常處理
- 連接超時:檢查URI配置和網絡連通性,適當增加
connectTimeoutMS
- 查詢無結果:確認數據存在且索引生效,可使用
hint()
強制指定索引 - 事務沖突:確保操作集合已存在并啟用副本集
- 內存溢出:聚合查詢時添加
allowDiskUse(true)
完整代碼示例可參考CSDN專題教程,生產環境建議結合分庫分表、讀寫分離等高級架構設計。