You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中使用MongoRepository查询MongoDB嵌套对象数据

SpringBoot + MongoDB 实现嵌套数组过滤查询方案

先定义对应实体类

首先要创建与MongoDB文档结构匹配的实体类,注意修正你原始数据里的字段笔误(kay1建议统一为key1,避免映射错误):

1. 嵌套的TestData类

public class TestData {
    private String resultData1;
    private String resultData2;
    
    // 生成无参、全参构造器
    // 生成getter、setter方法
}

2. 数组元素DataItem类

public class DataItem {
    private String key1; // 若要保留原始笔误,此处改为kay1
    private boolean isValid;
    private List<TestData> testData;
    
    // 生成无参、全参构造器
    // 生成getter、setter方法
}

3. 主实体类StudentRecord

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;

@Document(collection = "student_records") // 替换为你的MongoDB集合名
public class StudentRecord {
    @Id
    private Integer id;
    private String uid;
    private List<DataItem> data;
    
    // 生成无参、全参构造器
    // 生成getter、setter方法
}

两种实现方式

方式一:MongoTemplate聚合查询(推荐,精准控制结果)

通过MongoTemplate的聚合管道,先匹配uid,再过滤data数组中isValid=true的元素:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

@Service
public class StudentRecordService {
    private final MongoTemplate mongoTemplate;

    // 构造注入MongoTemplate
    public StudentRecordService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public StudentRecord getValidStudentData(String targetUid) {
        // 构建聚合管道
        Aggregation aggregation = Aggregation.newAggregation(
                // 第一步:匹配uid对应的文档
                Aggregation.match(Criteria.where("uid").is(targetUid)),
                // 第二步:过滤data数组,只保留isValid=true的元素
                Aggregation.project("_id", "uid")
                        .and(Aggregation.filter("data", "item", 
                             Aggregation.Criteria.where("item.isValid").is(true)))
                        .as("data")
        );

        // 执行聚合查询并返回结果
        AggregationResults<StudentRecord> results = mongoTemplate.aggregate(
                aggregation, 
                "student_records", // 对应你的集合名
                StudentRecord.class
        );
        return results.getUniqueMappedResult();
    }
}

方式二:MongoRepository自定义聚合查询(简洁写法)

通过Repository接口的@Aggregation注解直接写MongoDB聚合语句:

import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.Optional;

public interface StudentRecordRepository extends MongoRepository<StudentRecord, Integer> {

    @Aggregation(pipeline = {
            "{ $match: { uid: ?0 } }",
            "{ $project: { _id: 1, uid: 1, data: { $filter: { input: '$data', as: 'item', cond: { $eq: ['$$item.isValid', true] } } } } }"
    })
    Optional<StudentRecord> findByUidWithValidData(String uid);
}

在Service中调用Repository:

import org.springframework.stereotype.Service;
import java.util.Optional;

@Service
public class StudentRecordService {
    private final StudentRecordRepository recordRepository;

    public StudentRecordService(StudentRecordRepository recordRepository) {
        this.recordRepository = recordRepository;
    }

    public StudentRecord getValidStudentData(String targetUid) {
        return recordRepository.findByUidWithValidData(targetUid).orElse(null);
    }
}

控制器调用示例

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StudentRecordController {
    private final StudentRecordService recordService;

    public StudentRecordController(StudentRecordService recordService) {
        this.recordService = recordService;
    }

    @GetMapping("/students/{uid}")
    public StudentRecord getValidData(@PathVariable String uid) {
        return recordService.getValidStudentData(uid);
    }
}

关键说明

  • 两种方式最终都会返回你期望的结果:仅保留uid=uniqueId100文档中data数组里isValid=true的元素。
  • 若坚持保留原始数据中的kay1字段,需将DataItem类中的key1改为kay1,保证字段映射一致。

内容的提问来源于stack exchange,提问作者ngi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:20:31