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

如何在Spring Data MongoDB中关联Room与RoomType集合并通过Java Query实现?

在Spring Data MongoDB中用Query实现集合关联查询

对应你给出的SQL select * from Room r inner join RoomType rt on r.roomTypeId=rt._id,可以通过Spring Data MongoDB的**Aggregation(聚合)**结合$lookup操作来实现,以下是具体实现步骤:

1. 定义实体类

先创建与MongoDB集合对应的实体类,以及用于接收关联结果的DTO:

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

// Room集合实体
@Document(collection = "Room")
public class Room {
    @Id
    private String id;
    private String agentId;
    private String roomName;
    private String note;
    private String roomStatus;
    private String roomTypeId; // 关联RoomType的_id字段
    private String createdBy;
    private Date createdAt;
    private String updatedBy;
    private Date updatedAt;
    private boolean isDeleted;

    // 生成Getters和Setters
}

// RoomType集合实体
@Document(collection = "RoomType")
public class RoomType {
    @Id
    private String id;
    private String roomTypeName;
    private String note;
    private String createdBy;
    private Date createdAt;
    private String updatedBy;
    private Date updatedAt;
    private boolean isDeleted;

    // 生成Getters和Setters
}

// 关联结果DTO,用于封装Room和对应的RoomType数据
public class RoomWithTypeDTO {
    private Room room;
    private RoomType roomType;

    // 生成Getters和Setters
}

2. 实现关联查询逻辑

使用MongoTemplate执行聚合操作,通过$lookup完成关联,再通过match过滤实现inner join效果:

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.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class RoomService {

    private final MongoTemplate mongoTemplate;

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

    public List<RoomWithTypeDTO> getRoomsJoinedWithType() {
        // 定义Lookup操作:关联RoomType集合
        LookupOperation lookupRoomType = LookupOperation.newLookup()
                .from("RoomType") // 目标关联集合名
                .localField("roomTypeId") // Room集合中的关联字段
                .foreignField("_id") // RoomType集合中的匹配字段
                .as("roomType"); // 关联结果的别名

        // 构建聚合管道:先关联,再过滤掉未匹配到RoomType的记录(实现inner join)
        Aggregation aggregation = Aggregation.newAggregation(
                lookupRoomType,
                Aggregation.match(Criteria.where("roomType").size(1)) // 确保roomType数组有一条匹配数据
        );

        // 执行聚合查询,映射到DTO
        AggregationResults<RoomWithTypeDTO> results = mongoTemplate.aggregate(
                aggregation, "Room", RoomWithTypeDTO.class
        );

        return results.getMappedResults();
    }
}

3. 关键说明

  • MongoDB的$lookup默认是**左连接(left join)**行为,会返回所有Room记录,即使没有匹配的RoomType;通过Aggregation.match(Criteria.where("roomType").size(1))可以过滤掉未匹配的记录,实现SQL中inner join的效果。
  • 如果不需要严格的inner join,只需移除match步骤即可得到左连接结果。
  • 返回的RoomWithTypeDTO中,roomType会自动映射为匹配的RoomType对象(因为我们指定了别名roomType,且DTO中对应字段名一致)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:17:50