1. 项目配置

1.1 Maven 依赖

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Spring Boot Starter Data MongoDB -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    
    <!-- Lombok (可选) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

1.2 application.yml 配置

spring:
  data:
    mongodb:
      # MongoDB 连接配置
      uri: mongodb://localhost:27017/testdb
      # 或者使用以下配置
      # host: localhost
      # port: 27017
      # database: testdb
      # username: root
      # password: password
      
  # 应用配置
  application:
    name: mongodb-demo

server:
  port: 8080

logging:
  level:
    org.springframework.data.mongodb: DEBUG

2. 实体类定义

package com.example.mongodb.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.time.LocalDateTime;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "users")  // 指定集合名称
public class User {
    
    @Id
    private String id;
    
    @Field("user_name")
    private String username;
    
    private String email;
    
    private Integer age;
    
    private List<String> roles;
    
    @Field("created_at")
    private LocalDateTime createdAt;
    
    @Field("updated_at")
    private LocalDateTime updatedAt;
    
    // 嵌套文档
    private Address address;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Address {
        private String city;
        private String street;
        private String zipCode;
    }
}

3. Repository 接口

package com.example.mongodb.repository;

import com.example.mongodb.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserRepository extends MongoRepository<User, String> {
    
    // 自定义查询方法
    List<User> findByUsername(String username);
    
    List<User> findByAgeGreaterThan(int age);
    
    List<User> findByRolesContains(String role);
}

4. MongoTemplate 服务类

4.1 数据集管理服务

package com.example.mongodb.service;

import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class DatasetService {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    /**
     * 获取所有数据集(集合)名称
     * @return 数据集名称列表
     */
    public List<String> getAllDatasets() {
        List<String> datasetNames = new ArrayList<>();
        
        try {
            MongoDatabase database = mongoTemplate.getDb();
            MongoIterable<String> collectionNames = database.listCollectionNames();
            
            for (String name : collectionNames) {
                datasetNames.add(name);
                log.info("发现数据集: {}", name);
            }
            
            // 或者使用 MongoTemplate 的方法
            // datasetNames = new ArrayList<>(mongoTemplate.getCollectionNames());
            
        } catch (Exception e) {
            log.error("获取数据集列表失败", e);
            throw new RuntimeException("获取数据集列表失败", e);
        }
        
        return datasetNames;
    }
    
    /**
     * 获取所有数据集(集合)名称和统计信息
     * @return 数据集详细信息列表
     */
    public List<DatasetInfo> getAllDatasetsWithInfo() {
        List<DatasetInfo> datasets = new ArrayList<>();
        
        try {
            List<String> collectionNames = getAllDatasets();
            
            for (String collectionName : collectionNames) {
                DatasetInfo info = new DatasetInfo();
                info.setName(collectionName);
                
                try {
                    // 获取文档数量
                    long count = mongoTemplate.getCollection(collectionName).countDocuments();
                    info.setDocumentCount(count);
                    
                    // 获取集合统计信息
                    Document stats = mongoTemplate.getDb().runCommand(
                        new Document("collStats", collectionName)
                    );
                    
                    if (stats.containsKey("size")) {
                        info.setSizeInBytes(stats.getLong("size"));
                        info.setSizeInMB(stats.getLong("size") / (1024.0 * 1024.0));
                    }
                    
                    if (stats.containsKey("storageSize")) {
                        info.setStorageSizeInBytes(stats.getLong("storageSize"));
                    }
                    
                    if (stats.containsKey("indexes")) {
                        info.setIndexCount(stats.getList("indexes", Document.class).size());
                    }
                    
                } catch (Exception e) {
                    log.warn("获取集合 {} 统计信息失败: {}", collectionName, e.getMessage());
                    info.setDocumentCount(0L);
                }
                
                datasets.add(info);
            }
            
        } catch (Exception e) {
            log.error("获取数据集详细信息失败", e);
            throw new RuntimeException("获取数据集详细信息失败", e);
        }
        
        return datasets;
    }
    
    /**
     * 删除指定数据集(集合)
     * @param collectionName 集合名称
     * @return 是否删除成功
     */
    public boolean deleteDataset(String collectionName) {
        try {
            // 检查集合是否存在
            if (!mongoTemplate.collectionExists(collectionName)) {
                log.warn("数据集 {} 不存在", collectionName);
                return false;
            }
            
            // 删除集合
            mongoTemplate.dropCollection(collectionName);
            log.info("数据集 {} 删除成功", collectionName);
            
            return true;
            
        } catch (Exception e) {
            log.error("删除数据集 {} 失败", collectionName, e);
            throw new RuntimeException("删除数据集失败: " + collectionName, e);
        }
    }
    
    /**
     * 批量删除多个数据集
     * @param collectionNames 数据集名称列表
     * @return 删除结果
     */
    public BatchDeleteResult batchDeleteDatasets(List<String> collectionNames) {
        BatchDeleteResult result = new BatchDeleteResult();
        
        for (String name : collectionNames) {
            try {
                boolean success = deleteDataset(name);
                if (success) {
                    result.getSuccess().add(name);
                } else {
                    result.getFailed().add(name + " (不存在)");
                }
            } catch (Exception e) {
                result.getFailed().add(name + " (错误: " + e.getMessage() + ")");
            }
        }
        
        return result;
    }
    
    /**
     * 删除符合条件的数据集(过滤系统集合)
     * @param pattern 名称模式(支持通配符)
     * @param excludeSystemCollections 是否排除系统集合
     * @return 删除结果
     */
    public BatchDeleteResult deleteDatasetsByPattern(String pattern, boolean excludeSystemCollections) {
        List<String> allDatasets = getAllDatasets();
        List<String> toDelete = new ArrayList<>();
        
        for (String dataset : allDatasets) {
            // 检查是否匹配模式
            boolean matches = dataset.matches(pattern.replace("*", ".*"));
            
            // 检查是否系统集合
            boolean isSystemCollection = dataset.startsWith("system.") || dataset.equals("admin");
            
            if (matches && (!excludeSystemCollections || !isSystemCollection)) {
                toDelete.add(dataset);
            }
        }
        
        return batchDeleteDatasets(toDelete);
    }
    
    /**
     * 数据集信息类
     */
    @Data
    public static class DatasetInfo {
        private String name;              // 数据集名称
        private Long documentCount;       // 文档数量
        private Long sizeInBytes;         // 数据大小(字节)
        private Double sizeInMB;          // 数据大小(MB)
        private Long storageSizeInBytes;  // 存储大小(字节)
        private Integer indexCount;       // 索引数量
    }
    
    /**
     * 批量删除结果类
     */
    @Data
    public static class BatchDeleteResult {
        private List<String> success = new ArrayList<>();
        private List<String> failed = new ArrayList<>();
        
        public int getTotal() {
            return success.size() + failed.size();
        }
    }
}

4.2 数据操作服务

package com.example.mongodb.service;

import com.example.mongodb.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Slf4j
@Service
public class UserService {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    /**
     * 创建集合(如果不存在)
     */
    public void createCollectionIfNotExists() {
        String collectionName = "users";
        
        if (!mongoTemplate.collectionExists(collectionName)) {
            mongoTemplate.createCollection(collectionName);
            log.info("创建集合: {}", collectionName);
        }
    }
    
    /**
     * 插入用户数据
     */
    public User insertUser(User user) {
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        return mongoTemplate.insert(user);
    }
    
    /**
     * 批量插入用户数据
     */
    public List<User> insertUsers(List<User> users) {
        LocalDateTime now = LocalDateTime.now();
        users.forEach(user -> {
            user.setCreatedAt(now);
            user.setUpdatedAt(now);
        });
        return mongoTemplate.insertAll(users);
    }
    
    /**
     * 查询所有用户
     */
    public List<User> findAllUsers() {
        return mongoTemplate.findAll(User.class);
    }
    
    /**
     * 分页查询用户
     */
    public List<User> findUsersWithPagination(int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        Query query = new Query().with(pageable);
        return mongoTemplate.find(query, User.class);
    }
    
    /**
     * 根据条件查询用户
     */
    public List<User> findUsersByCondition(String username, Integer minAge, Integer maxAge) {
        Query query = new Query();
        
        if (username != null && !username.trim().isEmpty()) {
            // 模糊查询
            Pattern pattern = Pattern.compile("^.*" + username + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("username").regex(pattern));
        }
        
        if (minAge != null || maxAge != null) {
            Criteria ageCriteria = Criteria.where("age");
            if (minAge != null) ageCriteria.gte(minAge);
            if (maxAge != null) ageCriteria.lte(maxAge);
            query.addCriteria(ageCriteria);
        }
        
        return mongoTemplate.find(query, User.class);
    }
    
    /**
     * 更新用户信息
     */
    public User updateUser(String userId, Map<String, Object> updates) {
        Query query = new Query(Criteria.where("id").is(userId));
        Update update = new Update();
        
        updates.forEach((key, value) -> {
            if (!"id".equals(key)) {  // 不更新ID
                update.set(key, value);
            }
        });
        update.set("updatedAt", LocalDateTime.now());
        
        return mongoTemplate.findAndModify(query, update, User.class);
    }
    
    /**
     * 删除用户
     */
    public boolean deleteUser(String userId) {
        Query query = new Query(Criteria.where("id").is(userId));
        return mongoTemplate.remove(query, User.class).getDeletedCount() > 0;
    }
    
    /**
     * 统计用户数量
     */
    public long countUsers() {
        return mongoTemplate.count(new Query(), User.class);
    }
    
    /**
     * 聚合查询:按城市统计用户
     */
    public List<Map> aggregateUsersByCity() {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.group("address.city")
                .count().as("userCount")
                .avg("age").as("averageAge"),
            Aggregation.sort(Sort.Direction.DESC, "userCount"),
            Aggregation.project("userCount", "averageAge")
                .and("_id").as("city")
        );
        
        AggregationResults<Map> results = mongoTemplate.aggregate(
            aggregation, "users", Map.class
        );
        
        return results.getMappedResults();
    }
    
    /**
     * 创建索引
     */
    public void createIndexes() {
        mongoTemplate.indexOps(User.class).ensureIndex(
            new org.springframework.data.mongodb.core.index.Index()
                .on("username", Sort.Direction.ASC)
                .unique()
        );
        
        mongoTemplate.indexOps(User.class).ensureIndex(
            new org.springframework.data.mongodb.core.index.Index()
                .on("email", Sort.Direction.ASC)
        );
        
        log.info("用户集合索引创建完成");
    }
}

5. 控制器类

package com.example.mongodb.controller;

import com.example.mongodb.entity.User;
import com.example.mongodb.service.DatasetService;
import com.example.mongodb.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/datasets")
@Tag(name = "数据集管理", description = "MongoDB数据集管理接口")
public class DatasetController {
    
    @Autowired
    private DatasetService datasetService;
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/list")
    @Operation(summary = "获取所有数据集", description = "获取MongoDB中所有集合的名称")
    public ResponseEntity<List<String>> getAllDatasets() {
        List<String> datasets = datasetService.getAllDatasets();
        return ResponseEntity.ok(datasets);
    }
    
    @GetMapping("/list-with-info")
    @Operation(summary = "获取数据集详细信息", description = "获取所有集合的详细信息,包括文档数量、大小等")
    public ResponseEntity<List<DatasetService.DatasetInfo>> getAllDatasetsWithInfo() {
        List<DatasetService.DatasetInfo> datasets = datasetService.getAllDatasetsWithInfo();
        return ResponseEntity.ok(datasets);
    }
    
    @DeleteMapping("/{collectionName}")
    @Operation(summary = "删除数据集", description = "删除指定的数据集(集合)")
    public ResponseEntity<Map<String, Object>> deleteDataset(
            @PathVariable String collectionName,
            @RequestParam(defaultValue = "false") boolean force) {
        
        // 如果是系统集合且不是强制删除,则拒绝
        if (!force && (collectionName.startsWith("system.") || collectionName.equals("admin"))) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "系统集合不允许删除,请使用 force=true 参数强制删除"
            ));
        }
        
        boolean success = datasetService.deleteDataset(collectionName);
        
        if (success) {
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "数据集删除成功",
                "collectionName", collectionName
            ));
        } else {
            return ResponseEntity.ok(Map.of(
                "success", false,
                "message", "数据集不存在",
                "collectionName", collectionName
            ));
        }
    }
    
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除数据集", description = "批量删除多个数据集")
    public ResponseEntity<DatasetService.BatchDeleteResult> batchDeleteDatasets(
            @RequestBody List<String> collectionNames) {
        DatasetService.BatchDeleteResult result = datasetService.batchDeleteDatasets(collectionNames);
        return ResponseEntity.ok(result);
    }
    
    @PostMapping("/demo/init")
    @Operation(summary = "初始化演示数据", description = "创建演示集合和插入测试数据")
    public ResponseEntity<Map<String, Object>> initDemoData() {
        try {
            // 创建用户集合
            userService.createCollectionIfNotExists();
            
            // 创建索引
            userService.createIndexes();
            
            // 插入测试数据
            List<User> users = List.of(
                new User(null, "张三", "zhangsan@example.com", 25, 
                        List.of("admin", "user"), null, null,
                        new User.Address("北京", "朝阳区", "100001")),
                new User(null, "李四", "lisi@example.com", 30, 
                        List.of("user"), null, null,
                        new User.Address("上海", "浦东新区", "200001")),
                new User(null, "王五", "wangwu@example.com", 28, 
                        List.of("manager", "user"), null, null,
                        new User.Address("广州", "天河区", "510001"))
            );
            
            userService.insertUsers(users);
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "演示数据初始化成功",
                "userCount", userService.countUsers()
            ));
            
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "演示数据初始化失败: " + e.getMessage()
            ));
        }
    }
    
    @DeleteMapping("/demo/clean")
    @Operation(summary = "清理演示数据", description = "删除演示集合")
    public ResponseEntity<Map<String, Object>> cleanDemoData() {
        try {
            boolean success = datasetService.deleteDataset("users");
            
            return ResponseEntity.ok(Map.of(
                "success", success,
                "message", success ? "演示数据清理成功" : "演示数据不存在"
            ));
            
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "演示数据清理失败: " + e.getMessage()
            ));
        }
    }
    
    @GetMapping("/demo/users")
    @Operation(summary = "获取演示用户数据", description = "查询用户集合中的所有数据")
    public ResponseEntity<List<User>> getDemoUsers() {
        List<User> users = userService.findAllUsers();
        return ResponseEntity.ok(users);
    }
}

6. 配置类

package com.example.mongodb.config;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.example.mongodb.repository")
public class MongoConfig {
    
    @Value("${spring.data.mongodb.uri}")
    private String mongoUri;
    
    @Bean
    public MongoClient mongoClient() {
        ConnectionString connectionString = new ConnectionString(mongoUri);
        MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(connectionString)
                .build();
        return MongoClients.create(settings);
    }
    
    @Bean
    public MongoDatabaseFactory mongoDatabaseFactory(MongoClient mongoClient) {
        return new SimpleMongoClientDatabaseFactory(mongoClient, "testdb");
    }
    
    @Bean
    public MongoTemplate mongoTemplate(
            MongoDatabaseFactory mongoDatabaseFactory,
            MappingMongoConverter converter) {
        return new MongoTemplate(mongoDatabaseFactory, converter);
    }
    
    @Bean
    public MappingMongoConverter mappingMongoConverter(
            MongoDatabaseFactory factory, 
            MongoMappingContext context) {
        
        DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, context);
        
        // 去掉 _class 字段
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        
        return converter;
    }
}

7. 主启动类

package com.example.mongodb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;

@SpringBootApplication
@EnableMongoAuditing  // 启用审计功能,自动填充创建时间、更新时间等
public class MongodbDemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(MongodbDemoApplication.class, args);
    }
}

8. 使用示例

8.1 REST API 调用示例

# 1. 获取所有数据集
curl -X GET http://localhost:8080/api/datasets/list

# 2. 获取数据集详细信息
curl -X GET http://localhost:8080/api/datasets/list-with-info

# 3. 初始化演示数据
curl -X POST http://localhost:8080/api/datasets/demo/init

# 4. 获取演示用户数据
curl -X GET http://localhost:8080/api/datasets/demo/users

# 5. 删除指定数据集
curl -X DELETE "http://localhost:8080/api/datasets/users"

# 6. 批量删除数据集
curl -X DELETE http://localhost:8080/api/datasets/batch \
  -H "Content-Type: application/json" \
  -d '["users", "orders", "products"]'

# 7. 强制删除系统集合(谨慎使用)
curl -X DELETE "http://localhost:8080/api/datasets/system.indexes?force=true"

8.2 单元测试

package com.example.mongodb.service;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class DatasetServiceTest {
    
    @Autowired
    private DatasetService datasetService;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    @BeforeEach
    void setUp() {
        // 清理测试数据
        if (mongoTemplate.collectionExists("test_collection_1")) {
            mongoTemplate.dropCollection("test_collection_1");
        }
        if (mongoTemplate.collectionExists("test_collection_2")) {
            mongoTemplate.dropCollection("test_collection_2");
        }
        
        // 创建测试集合
        mongoTemplate.createCollection("test_collection_1");
        mongoTemplate.createCollection("test_collection_2");
        
        // 插入测试数据
        mongoTemplate.insert(new TestDocument("test1"), "test_collection_1");
        mongoTemplate.insert(new TestDocument("test2"), "test_collection_1");
        mongoTemplate.insert(new TestDocument("test3"), "test_collection_2");
    }
    
    @Test
    void testGetAllDatasets() {
        List<String> datasets = datasetService.getAllDatasets();
        
        assertNotNull(datasets);
        assertTrue(datasets.contains("test_collection_1"));
        assertTrue(datasets.contains("test_collection_2"));
        
        System.out.println("所有数据集: " + datasets);
    }
    
    @Test
    void testGetAllDatasetsWithInfo() {
        List<DatasetService.DatasetInfo> datasets = datasetService.getAllDatasetsWithInfo();
        
        assertNotNull(datasets);
        
        // 查找测试集合信息
        DatasetService.DatasetInfo collection1 = datasets.stream()
                .filter(info -> info.getName().equals("test_collection_1"))
                .findFirst()
                .orElse(null);
        
        assertNotNull(collection1);
        assertEquals(2L, collection1.getDocumentCount());
        
        System.out.println("数据集详细信息:");
        datasets.forEach(info -> {
            System.out.printf("%s: %d 个文档, %.2f MB%n",
                    info.getName(), info.getDocumentCount(), info.getSizeInMB());
        });
    }
    
    @Test
    void testDeleteDataset() {
        // 删除数据集
        boolean result = datasetService.deleteDataset("test_collection_1");
        
        assertTrue(result);
        assertFalse(mongoTemplate.collectionExists("test_collection_1"));
        assertTrue(mongoTemplate.collectionExists("test_collection_2"));
        
        // 删除不存在的集合
        boolean result2 = datasetService.deleteDataset("non_existent");
        assertFalse(result2);
    }
    
    @Test
    void testBatchDeleteDatasets() {
        List<String> toDelete = Arrays.asList("test_collection_1", "test_collection_2");
        
        DatasetService.BatchDeleteResult result = 
                datasetService.batchDeleteDatasets(toDelete);
        
        assertEquals(2, result.getTotal());
        assertEquals(2, result.getSuccess().size());
        assertEquals(0, result.getFailed().size());
        
        assertFalse(mongoTemplate.collectionExists("test_collection_1"));
        assertFalse(mongoTemplate.collectionExists("test_collection_2"));
    }
    
    // 测试文档类
    static class TestDocument {
        private String id;
        private String name;
        
        public TestDocument(String name) {
            this.name = name;
        }
        
        // getters and setters
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }
}

9. 安全注意事项

9.1 权限控制

package com.example.mongodb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/api/datasets/**").hasRole("ADMIN")  // 仅管理员可访问
                .antMatchers("/api/public/**").permitAll()        // 公共接口
                .anyRequest().authenticated()
                .and()
            .httpBasic()  // 使用HTTP Basic认证
                .and()
            .csrf().disable();  // 禁用CSRF,根据实际情况配置
    }
}

9.2 防止误删除

package com.example.mongodb.service;

import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Component
public class CollectionProtectionService {
    
    // 受保护的系统集合
    private static final Set<String> PROTECTED_COLLECTIONS = new HashSet<>(Arrays.asList(
        "system.users",
        "system.roles",
        "system.version",
        "admin",
        "config",
        "local"
    ));
    
    /**
     * 检查集合是否受保护
     */
    public boolean isProtected(String collectionName) {
        return PROTECTED_COLLECTIONS.contains(collectionName) || 
               collectionName.startsWith("system.");
    }
    
    /**
     * 验证删除操作
     */
    public boolean canDelete(String collectionName, boolean force) {
        if (isProtected(collectionName)) {
            return force;  // 受保护的集合需要强制删除
        }
        return true;
    }
}

总结

通过以上实现,你可以:

  1. 获取所有数据集:使用 mongoTemplate.getCollectionNames()database.listCollectionNames()
  2. 删除指定数据集:使用 mongoTemplate.dropCollection(collectionName)
  3. 添加额外功能
    • 获取数据集统计信息
    • 批量删除操作
    • 防止误删除系统集合
    • 提供RESTful API接口

关键点:

  • 使用 MongoTemplate 操作 MongoDB
  • 区分系统集合和用户集合
  • 添加适当的异常处理和日志记录
  • 考虑生产环境的安全性和权限控制
  • 提供清晰的API文档和错误信息
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐