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

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

场景

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

数据结构

假设需要在下列文档中获取_id、name、age、address.city、address.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);
    }
}

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

相关推荐
高频因子挖掘机8 分钟前
股票 API 返回 HTTP 429 怎么办?Python 量化系统的限流排查与重试设计
后端·github·api
mldong11 分钟前
为了 token 自由,我把 jeeflow 工作流引擎用 MoonBit 写了一遍
后端·架构
高频因子挖掘机1 小时前
从回测到实盘:量化策略为什么不应该直接依赖行情 API
后端·github·api
大鸡腿同学9 小时前
手心向上,手心向下
后端
CCblandy9 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
凤山老林11 小时前
Spring Boot 集成 Sa-Token 实现高可用权限认证:登录鉴权、动态路由权限与接口防重放实战
spring boot·后端·sa-token·bootstrap
Bazingga12 小时前
一次推理的完整旅程:ReAct推理深度解析
后端
姜鱼问生13 小时前
Nginx gzip 压缩:一个配置让页面加载快 3 倍
后端·算法·架构
颜酱13 小时前
一栋商业大厦,讲清 InnoDB 的表空间、段、区和页
后端·mysql
码事漫谈13 小时前
1956 亿行数据该怎么存:金仓时序数据库的三个实测
后端