mongodb - 使用来自 Spring Data Mongo 的条件查询获取结果时更新文档中的字段之一
问题描述
使用条件查询我从 MongoDB 获取文档。我的要求是我想通过使用 Spring Data Mongo 中的 Criteria 查询子文档来更新父文档值中的字段。父文档是评论,嵌套文档是回复。我可以使用以下代码获取评论列表以及子文档,
Data Set:
{
"_id" : ObjectId("5cb726937a7148376094d393"),
"_class" : "vzi.cpei.Comments",
"text" : "first comment on money control",
"replies" : [
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b223639087",
"text" : "extract the traces",
"status" : true
},
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b153690087",
"text" : "replied deiberate",
"status" : false
},
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b153139087",
"text" : "Bgm",
"status" : true
}],
}
Response DTO:
public class CommentsDTO{
private String id;
private String text;
private List<Replies> replies;
private Integer totalReplies;
}
使用 Spring 数据 mongo Criteria 查询在 Spring 中编写的代码,
Query query = new Query();
Criteria criteria =Criteria.where("_id").is(new ObjectId("5efe3d1f8a2ef008249f72d9"));
query.addCriteria(criteria);
List<Comments> comments = mongoOps.find(query,"Comments",
CommentsDTO.class);
return comments;
在结果中,我想用状态为 true 的回复总数更新字段 repliesCount,因此预期的输出应该是,
{
"_id" : ObjectId("5cb726937a7148376094d393"),
"_class" : "vzi.cpei.Comments",
"text" : "first comment on money control",
"totalReplies" : 2
"replies" : [
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b223639087",
"text" : "extract the traces",
"status" : true
},
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b153690087",
"text" : "replied deiberate",
"status" : false
},
{
"_id" : "3cfef1cd-e0da-4883-86a4-17b153139087",
"text" : "Bgm",
"status" : true
}],
}
我很困惑在获取时在哪里执行此操作。
解决方案
您需要执行MongoDB 聚合。
的解释pipeline
- 我们将
$match
阶段应用于过滤结果(类似于.find(query)
) - 我们应用
$project
来转换文档结构并包含totalReplies
基于replies
值计算的字段
壳
db.Comments.aggregate([
{
$match: {
"_id": ObjectId("5cb726937a7148376094d393")
}
},
{
$project: {
_class: 1,
replies: 1,
totalReplies: {
$size: {
"$filter": {
input: "$replies.status",
as: "status",
cond: "$$status"
}
}
}
}
}
])
Spring-Mongo
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
...
Aggregation agg = Aggregation.newAggregation(
match(Criteria.where("_id").is(new ObjectId("5cb726937a7148376094d393"))),
project("_id", "_class", "replies").and(ArrayOperators.Size.lengthOfArray(
ArrayOperators.Filter.filter("replies.status").as("filter").by("$$filter")
)).as("totalReplies"));
//System.out.println(agg);
return mongoOps.aggregate(agg, mongoOps.getCollectionName(CommentsDTO.class), CommentsDTO.class);
编辑:旧版 Spring-boot 1.4.2
project("_id", "_class", "replies")
.and(AggregationFunctionExpressions.SIZE
.of(new BasicDBObject("$filter",
new BasicDBObject("input", "$replies.status")
.append("as", "status")
.append("cond", "$$status"))))
.as("totalReplies")
推荐阅读
- avro - 读取 3170 字节的 avro 文件会导致 0 条记录,所以我很困惑
- python - py4j.protocol.Py4JNetworkError:Java 端的答案为空
- java - 错误:变量总计可能尚未初始化
- c++ - 为 beaglebone black 交叉编译时无法链接 opencv-3.2.0
- c++ - 如何在c ++中的mysql_fetch_row(MYSQL _RES)中存储值行[i]
- c - 为什么在下面的代码中两个不同的变量具有相同的地址但不同的值?
- javacc - 如何根据 JavaCC 中的用户输入多次调用一个方法?
- javascript - 如何改进正则表达式,使其可以匹配谷歌脚本电子邮件刮板的电子邮件格式?
- webstorm - WebStorm 新版本断点不起作用
- python - 如何解决单源多目的地问题的不连续性?