Mongo 聚合,用该内部数组的计数替换内部数组结果数组
Mongo Aggregation, replacing array inside results in array with count of that inner array
我正在研究一种社交网络模式,并尝试使用聚合框架在管道期间更改文档以总结其中的一部分,特别是用数组的大小替换数据数组。
例如,给定这些原始文档,每个文档都有一个post数组,每个post都有一个点赞数组:
{ "_id": 1, "posts": [
{
"content": "foobar", "likes": [ "11", "12", "13" ]
}
] }
{ "_id": 2, "posts": [
{
"content": "foobar2", "likes": [ "22", "23" ]
}
] }
{ "_id": 3, "posts": [
{
"content": "foobar3", "likes": [ "33" ]
}
] }
(可以直接输入 mongoimport
)
在现实世界中,posts
数组中的元素很多,likes
数组中的元素更复杂。我需要 return 记录点赞数 ,而不是实际的点赞数本身,例如
{ _id: 1, posts: [
{ content: 'foobar', likeCount: 3 }
] },
{ _id: 2, posts: [
{ content: 'foobar2', likeCount: 2 }
] },
{ _id: 3, posts: [
{ content: 'foobar3', likeCount: 1 }
] }
$project
聚合阶段似乎很合适,但我无法获得产品所需的结果。例如
db.getCollection('test').aggregate([
{
$project: {
"posts.likeCount": { $size: "$posts.likes" }
}
}
])
给出:
{
"_id" : 2,
"posts" : [
{
"likeCount" : 1
}
]
}
{
"_id" : 3,
"posts" : [
{
"likeCount" : 1
}
]
}
{
"_id" : 1,
"posts" : [
{
"likeCount" : 1
}
]
}
$project
表达式中的 $posts.likes
用法似乎特别不对,因为 $posts
是一个数组。
我的输出文档如何包含此内部数组的聚合(计数),同时仍保持原始文档的结构?
我尝试了 $unwind
和 $replaceRoot
阶段来尝试找到解决方案,但最终得到的结构不太具体,失去了原始结构的周围字段。我一直在阅读 MongoDB 参考文档,并搜索 SO 和其他地方,但还没有找到解决方案。
如果您需要计算每个内容的点赞数,您需要先展开帖子:
db.test.aggregate([
{$unwind: "$posts"},
{$project: {
"posts.content" : 1,
"posts.likeCount": { $size: "$posts.likes" }
}},
{$group: {
_id: "$_id",
posts: {$push: "$posts"}
}}
])
您可以试试下面的聚合查询。 $map
迭代 posts
数组并使用 $size
计算 likes
.
的计数
db.collection.aggregate({
"$project": {
"posts": {
"$map": {
"input": "$posts",
"as": "post",
"in": {
"content": "$$post.content",
"likeCount": {
"$size": "$$post.likes"
}
}
}
}
}
})
我正在研究一种社交网络模式,并尝试使用聚合框架在管道期间更改文档以总结其中的一部分,特别是用数组的大小替换数据数组。
例如,给定这些原始文档,每个文档都有一个post数组,每个post都有一个点赞数组:
{ "_id": 1, "posts": [
{
"content": "foobar", "likes": [ "11", "12", "13" ]
}
] }
{ "_id": 2, "posts": [
{
"content": "foobar2", "likes": [ "22", "23" ]
}
] }
{ "_id": 3, "posts": [
{
"content": "foobar3", "likes": [ "33" ]
}
] }
(可以直接输入 mongoimport
)
在现实世界中,posts
数组中的元素很多,likes
数组中的元素更复杂。我需要 return 记录点赞数 ,而不是实际的点赞数本身,例如
{ _id: 1, posts: [
{ content: 'foobar', likeCount: 3 }
] },
{ _id: 2, posts: [
{ content: 'foobar2', likeCount: 2 }
] },
{ _id: 3, posts: [
{ content: 'foobar3', likeCount: 1 }
] }
$project
聚合阶段似乎很合适,但我无法获得产品所需的结果。例如
db.getCollection('test').aggregate([
{
$project: {
"posts.likeCount": { $size: "$posts.likes" }
}
}
])
给出:
{
"_id" : 2,
"posts" : [
{
"likeCount" : 1
}
]
}
{
"_id" : 3,
"posts" : [
{
"likeCount" : 1
}
]
}
{
"_id" : 1,
"posts" : [
{
"likeCount" : 1
}
]
}
$project
表达式中的 $posts.likes
用法似乎特别不对,因为 $posts
是一个数组。
我的输出文档如何包含此内部数组的聚合(计数),同时仍保持原始文档的结构?
我尝试了 $unwind
和 $replaceRoot
阶段来尝试找到解决方案,但最终得到的结构不太具体,失去了原始结构的周围字段。我一直在阅读 MongoDB 参考文档,并搜索 SO 和其他地方,但还没有找到解决方案。
如果您需要计算每个内容的点赞数,您需要先展开帖子:
db.test.aggregate([
{$unwind: "$posts"},
{$project: {
"posts.content" : 1,
"posts.likeCount": { $size: "$posts.likes" }
}},
{$group: {
_id: "$_id",
posts: {$push: "$posts"}
}}
])
您可以试试下面的聚合查询。 $map
迭代 posts
数组并使用 $size
计算 likes
.
db.collection.aggregate({
"$project": {
"posts": {
"$map": {
"input": "$posts",
"as": "post",
"in": {
"content": "$$post.content",
"likeCount": {
"$size": "$$post.likes"
}
}
}
}
}
})