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);
    }
}

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

相关推荐
子兮曰20 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰20 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝21 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码21 小时前
别再前后端各写一套表单校验了
java·后端
大勇前进1 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu1 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile1 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白801 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙1 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端
盖伦发发1 天前
软件工程SOLID 五大设计原则
后端·软件工程