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;
}
方法
通过创建扩展类对象,结合聚合管道方式进行解决核心逻辑如下
-
创建用户扩展类对象,并声明需要脱离嵌套的字段
javapublic class UserExtend extends User{ List<String> zipcode; } -
使用聚合管道
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);
}
}
以上为针对该问题的逻辑代码