MongoDB 如何在同一个查询中使用 slice 和 count
How to use slice and count in the same query in MongoDB
我需要在同一个查询中结合切片和计数,让我解释一下如何:
我有一个集合,将评论和他的回复存储在一个数组中
{
"_id" : ObjectId("5a6b14796ede6d5169ad68a7"),
"_class" : "com.social.model.comment.FirstLevelComment",
"contentId" : "5a12996de7e84e0001b93a91",
"replies" : [
{
"_id" : ObjectId("5a6b151a6ede6d5169ad68b1"),
"date" : ISODate("2018-01-26T11:46:34.202Z"),
"text" : "Reply 1"
},
{
"_id" : ObjectId("5a6b151d6ede6d5169ad68b2"),
"date" : ISODate("2018-01-26T11:46:37.357Z"),
"text" : "Reply 2"
},
{
"_id" : ObjectId("5a6b15206ede6d5169ad68b3"),
"date" : ISODate("2018-01-26T11:46:40.170Z"),
"text" : "Reply 3"
},
{
"_id" : ObjectId("5a6b15236ede6d5169ad68b4"),
"date" : ISODate("2018-01-26T11:46:43.025Z"),
"text" : "Reply 4"
},
{
"_id" : ObjectId("5a6b15256ede6d5169ad68b5"),
"date" : ISODate("2018-01-26T11:46:45.931Z"),
"text" : "Reply 5"
}
],
"date" : ISODate("2018-01-26T11:43:53.578Z"),
"text" : "This is the comment text"
}
每个一级评论都存储在一个单独的文档中,因此要检索属于某个内容的所有评论,我必须通过 "contentId" 字段进行查询匹配。
但是,我只想检索每条评论的前两个回复,所以我必须使用 $slice 运算符。
但是我也必须检索一条评论的回复总数,所以我可以在同一个查询中这样做吗?
我正在使用 spring 引导和 mongo 存储库,所以现在我的查询是这样的
@Query(value = "{}", fields = "{ replies : { $slice : 2 }}")
public Page<FirstLevelComment> findByContentId(String contentId, Pageable page);
但不知道如何添加对该查询的回复数。
编辑:
添加查询如 Alex P. said
db.comment.aggregate([
{$match:{contentId: "5a12996de7e84e0001b93a91"}},
{
$project: {
_id: 1,
_class: 1,
contentId: 1,
date: 1,
text: 1,
countSize: {$size: "$replies"},
sl: {$slice: ["$replies", 2]}
}
}])
如果您直接在 mongo 服务器上聚合,则必须这样做:
db.collection.aggregate([
{
$project: {
_id: 1,
_class: 1,
contentId: 1,
date: 1,
text: 1,
countSize: {$size: "$replies"},
sl: {$slice: ["$replies", 2]}
}
}
])
在 Java 应用程序中使用带有 Spring 数据的聚合框架时,您不能使用 MongoRepository
。您必须改用 MongoTemplate
。
查看 documentation 了解更多详情
您可以使用 MongoTemplate
尝试以下聚合。
ProjectionOperation project = Aggregation.project().and("replies").slice(2).as("first 2 comments").and("replies").size().as("count");
SkipOperation skip = Aggregation.skip(2L);
LimitOperation limit = Aggregation.limit(5);
Aggregation aggregation = Aggregation.newAggregation(project, skip, limit);
AggregationResults<Document> result = mongoTemplate.aggregate(aggregation, collectionname, Document.class);
我需要在同一个查询中结合切片和计数,让我解释一下如何:
我有一个集合,将评论和他的回复存储在一个数组中
{
"_id" : ObjectId("5a6b14796ede6d5169ad68a7"),
"_class" : "com.social.model.comment.FirstLevelComment",
"contentId" : "5a12996de7e84e0001b93a91",
"replies" : [
{
"_id" : ObjectId("5a6b151a6ede6d5169ad68b1"),
"date" : ISODate("2018-01-26T11:46:34.202Z"),
"text" : "Reply 1"
},
{
"_id" : ObjectId("5a6b151d6ede6d5169ad68b2"),
"date" : ISODate("2018-01-26T11:46:37.357Z"),
"text" : "Reply 2"
},
{
"_id" : ObjectId("5a6b15206ede6d5169ad68b3"),
"date" : ISODate("2018-01-26T11:46:40.170Z"),
"text" : "Reply 3"
},
{
"_id" : ObjectId("5a6b15236ede6d5169ad68b4"),
"date" : ISODate("2018-01-26T11:46:43.025Z"),
"text" : "Reply 4"
},
{
"_id" : ObjectId("5a6b15256ede6d5169ad68b5"),
"date" : ISODate("2018-01-26T11:46:45.931Z"),
"text" : "Reply 5"
}
],
"date" : ISODate("2018-01-26T11:43:53.578Z"),
"text" : "This is the comment text"
}
每个一级评论都存储在一个单独的文档中,因此要检索属于某个内容的所有评论,我必须通过 "contentId" 字段进行查询匹配。
但是,我只想检索每条评论的前两个回复,所以我必须使用 $slice 运算符。
但是我也必须检索一条评论的回复总数,所以我可以在同一个查询中这样做吗?
我正在使用 spring 引导和 mongo 存储库,所以现在我的查询是这样的
@Query(value = "{}", fields = "{ replies : { $slice : 2 }}")
public Page<FirstLevelComment> findByContentId(String contentId, Pageable page);
但不知道如何添加对该查询的回复数。
编辑: 添加查询如 Alex P. said
db.comment.aggregate([
{$match:{contentId: "5a12996de7e84e0001b93a91"}},
{
$project: {
_id: 1,
_class: 1,
contentId: 1,
date: 1,
text: 1,
countSize: {$size: "$replies"},
sl: {$slice: ["$replies", 2]}
}
}])
如果您直接在 mongo 服务器上聚合,则必须这样做:
db.collection.aggregate([
{
$project: {
_id: 1,
_class: 1,
contentId: 1,
date: 1,
text: 1,
countSize: {$size: "$replies"},
sl: {$slice: ["$replies", 2]}
}
}
])
在 Java 应用程序中使用带有 Spring 数据的聚合框架时,您不能使用 MongoRepository
。您必须改用 MongoTemplate
。
查看 documentation 了解更多详情
您可以使用 MongoTemplate
尝试以下聚合。
ProjectionOperation project = Aggregation.project().and("replies").slice(2).as("first 2 comments").and("replies").size().as("count");
SkipOperation skip = Aggregation.skip(2L);
LimitOperation limit = Aggregation.limit(5);
Aggregation aggregation = Aggregation.newAggregation(project, skip, limit);
AggregationResults<Document> result = mongoTemplate.aggregate(aggregation, collectionname, Document.class);