mongoTemplate 操作 mongodb 真是各种坑,springboot 官方文档上给到的案例不满足实际的需求
场景复现
现在有条 mongodb 的 sql 是这样的,文档 wallpaper 的 _id
关联文档 wallpaper_get_success 的 wallpaper_id
进行查询。
db.wallpaper.aggregate([ { $addFields: { "_id": { "$toString": "$_id" } } }, { "$lookup": { "from": "wallpaper_get_success", "localField": "_id", "foreignField": "wallpaper_id", "as": "success_id" } }, { "$match": { "success_id": { "$ne": [] } } }, { "$sample": { "size": 5 } } ])
然后呢,下面这一节是必不可少的,因为有这个问题: mongodb 连接查询,localField 使用_id 进行匹配不生效
{ $addFields: { "_id": { "$toString": "$_id" } } }
但是数据库操作很 sql,转换成 Java 代码就日狗了,newAggregation 中 lookup,match,sample 操作都可以,但是 addFields 操作不行
Aggregation aggregation = newAggregation( Aggregation.fields(""), //这一截是有问题的 lookup("wallpaper_get_success", "_id", "wallpaper_id", "success_id"), match(Criteria.where("success_id").ne(new WallpaperGetSuccess[]{})), sample(5) );
网上对于这个的操作几乎没有,后来还是在 stackoverflow 找到的
解决办法
原文:How can I implement addFields mongoDB query in Java
其实也就是,addFields 改成 new Document
关键点: 引入的 Document
类是,而不是 spring-boot-data-mongo 中的
import org.bson.Document;
代码如下
import org.bson.Document;//关键的引入 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.*; import static org.springframework.data.mongodb.core.aggregation.Aggregation.*; import org.springframework.data.mongodb.core.query.Collation; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.stereotype.Component; Aggregation aggregation = newAggregation( aoc -> new Document("$addFields",new Document("_id",new Document("$toString","$_id"))), lookup("wallpaper_get_success", "_id", "wallpaper_id", "success_id"), match(Criteria.where("success_id").ne(new WallpaperGetSuccess[]{})), sample(5) );
当然你也可以不使用 lambda 表达式,如下
这里比较一下原生 sql 和 java 代码
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于