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

Spring Boot集成MongoDB如何将嵌套数组字段提取为值数组

解决方案

有三种常用实现方式,可根据你的业务场景选择:

方案1:MongoDB聚合查询直接返回目标结构(推荐,数据库层面处理性能更高)

通过MongoDB的$map聚合操作直接提取嵌套数组的指定字段,无需后续Java代码转换:

// 自定义接收结果的DTO
public class AssignmentResp {
    private String title;
    private List<String> docs;
    // 补全getter、setter方法
}

// Repository层聚合查询实现
public List<AssignmentResp> getAssignments(final String uID) {
    MatchOperation matchOp = Aggregation.match(
        Criteria.where(CREATEDBY).is(uID)
            .orOperator(
                Criteria.where("docs.0").exists(true),
                Criteria.where("versionchecked").is(true)
            )
    );
    ProjectionOperation projectOp = Aggregation.project("title")
        .and(ArrayOperators.Map.arrayOf("docs")
            .as("docItem")
            .andApply(DocumentExpression.parse("$$docItem.fileId"))
        ).as("docs");
    Aggregation aggregation = Aggregation.newAggregation(matchOp, projectOp);
    return mongoTemplate.aggregate(aggregation, "assignemnt", AssignmentResp.class).getMappedResults();
}

方案2:业务层手动转换结果(改造成本最低,不修改原有查询逻辑)

保留你现有查询逻辑,在返回给接口前通过Stream流提取字段转换为目标结构:

// 先定义返回用的DTO
public class AssignmentResp {
    private String title;
    private List<String> docs;
    // 补全getter、setter方法
}

// 业务层转换逻辑
List<Assignment> originList = assignmentRepository.getAssignments(uID);
List<AssignmentResp> respList = originList.stream().map(origin -> {
    AssignmentResp resp = new AssignmentResp();
    resp.setTitle(origin.getTitle());
    List<String> fileIdList = origin.getDocs().stream()
        .map(Docs::getFileId)
        .toList();
    resp.setDocs(fileIdList);
    return resp;
}).toList();

方案3:Jackson自定义序列化(无侵入,无需修改业务和查询代码)

如果仅需要接口返回时自动转换,其他场景仍需要保留原有List<Docs>结构,可以通过Jackson序列化注解实现:

  1. 自定义序列化器
public class DocsToFileIdSerializer extends JsonSerializer<List<Docs>> {
    @Override
    public void serialize(List<Docs> docs, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        List<String> fileIds = docs.stream().map(Docs::getFileId).toList();
        gen.writeObject(fileIds);
    }
}
  1. 在Assignment类的docs字段上加注解
@JsonSerialize(using = DocsToFileIdSerializer.class)
private List<Docs> docs;

内容的提问来源于stack exchange,提问作者Kaveen M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 01:06:00