mongo数据库中获取嵌套指定字段方式

mongo数据库中获取嵌套指定字段方式

场景

在mongo数据库中,由于内存等性能原因不能获取整个文档,且需要获取文档中嵌套的部分字段值(其余字段值不需要),并将字段提取到嵌套外的情况下,通过MongoTemplate在软件层面获取指定字段的方法。

数据结构

假设需要在下列文档中获取_idnameageaddress.cityaddress.zipcode字段,无需获取address.street字段

mongo数据库中格式如下

json 复制代码
{
    "_id" : "1",
    "name" : "zhangsan",
    "age" : NumberInt(18),
    "address" : {
        "city" : "北京市",
        "street" : "海淀街道",
        "zipcode" : [
            "100080",
            "100000"
        ]
    },
    "_class" : "com.example.demo.dto.User"
}

Java中类结构如下

java 复制代码
public class User {
    @Id
    public String id;
    public String name;
    public Integer age;
    public Address address;
}

public class Address {
    public String city;
    public String street;
    public List<String> zipcode;
}

方法

通过创建扩展类对象,结合聚合管道方式进行解决核心逻辑如下

  1. 创建用户扩展类对象,并声明需要脱离嵌套的字段

    java 复制代码
    public class UserExtend extends User{
        List<String> zipcode;
    }
  2. 使用聚合管道

    java 复制代码
    //构建基础聚合管道
    List<AggregationOperation> operations = new ArrayList<>();
    operations.add(Aggregation.project(new String[]{"_id","name", "age"})
            .and("address.city").as("city")
            .and("address.zipcode").as("zipcode")
    );
    //其他还可按需加入
    //查询
    Aggregation aggregation = Aggregation.newAggregation(operations);
    AggregationResults<UserExtend> results = mongoTemplate.aggregate(
            aggregation,
            "userInfo",
            UserExtend.class
    );
    List<UserExtend> mappedResults = results.getMappedResults();

完整代码逻辑如下

代码

controller层

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    UserService userService;

    @RequestMapping(value = "/findWithoutStreet", method = RequestMethod.POST)
    public Result getUserWithoutStreet(@RequestParam String id) {
        return userService.getUserWithoutStreet(id);
    }

}

service层

java 复制代码
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Override
    public Result getUserWithoutStreet(String id) {
        User user = userDao.getUserWithoutStreet(id);
        return Result.success(user);
    }
    
}

dao层

java 复制代码
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public User getUserWithoutStreet(String id) {
        Query query = new Query();
        query.addCriteria(
                Criteria.where("_id").is(id)
        );
        //构建基础聚合管道
        List<AggregationOperation> operations = new ArrayList<>();
        operations.add(Aggregation.project(new String[]{"_id","name", "age"})
                .and("address.city").as("city")
                .and("address.zipcode").as("zipcode")
        );
        //其他还可按需加入

        //查询
        Aggregation aggregation = Aggregation.newAggregation(operations);
        AggregationResults<UserExtend> results = mongoTemplate.aggregate(
                aggregation,
                "userInfo",
                UserExtend.class
        );
        List<UserExtend> mappedResults = results.getMappedResults();
        return mappedResults.get(0);
    }
}

以上为针对该问题的逻辑代码

相关推荐
用户9416146933655 小时前
Python 量化数据处理技巧:复权、对齐、缺失值与换手率计算(附实战代码)
后端
凌风1145 小时前
java个人学习笔记001-原生java集成rabbitMQ的使用
后端
AI_大白5 小时前
Codex 接入实时行情 MCP:从配置、鉴权到字段踩坑
后端·架构
Xidaoapi5 小时前
Python从零构建AI Agent:让大模型学会思考和行动
后端
YOU OU6 小时前
SpringBoot 配置文件
java·spring boot·后端
JavaAgent架构师7 小时前
Java调用Claude API完整代码(Spring Boot + WebClient + 流式输出)
人工智能·后端
子兮曰7 小时前
GEO 生成式引擎优化完全指南:让你的内容成为 AI 的默认答案
前端·后端·seo
木雷坞7 小时前
小团队 CI runner 排队:从镜像拉取到缓存策略的排查记录
后端
用户713874229007 小时前
深入理解 ASP.NET Core 中的 IActionResult
后端