Reputation: 551
So I have this structure in my MongoDB instance.
{
"post_body": "test",
"author": "test1",
"comments":[
{
"comment_body": "comment test",
"comment_author": "test2",
"replies": [
{
"reply_body": "reply test1",
"reply_author": "test3"
},
{
"reply_body": "reply test2",
"reply_author": "test2"
}
]
}
]
}
And I want to get the total count of comments + replies.
So my desired output should be
{
"post_body": "test"
"author": "test1",
"comment_count": 3
}
So far using $project
only returns the total count of comments only. I want to get the total of comments + replies
Upvotes: 1
Views: 740
Reputation: 5466
Using Aggregation Pipeline we can get the desired result
Below query uses Pipeline Stages $project, $unwind and Pipeline operators $size and $sum
db.collection_name.aggregate([
{ $project: {
"post_body": 1,
"author": 1,
"comments":1,
"comments_size":{$size: "$comments" }
}
},
{ $unwind: "$comments" },
{ $project: {
"post_body": 1,
"author": 1,
"comments":1,
"comments_size":1,
"replies_size" : {$size: "$comments.replies"}
}
},
{ $project: {
"_id":0,
"post_body": 1,
"author": 1,
"comments_count":{$sum:["$comments_size", "$replies_size"]}
}
}
])
First part of the aggregation query uses $project and we are just projecting the required attributes to next stage and also we are finding the size of the comments array. The size of the comments array is stored in a temporary attribute comments_size
Second part uses $unwind to break the nested array in comments
and comments.replies
, the comments
array is unwinded and comments.replies
array is kept unaltered
Third part uses $project to find the size of the replies and it is stored in a temporary attribute replies_size
Fourth and final part uses $project again with $sum of comments_size
and replies_size
to get the desired result
Upvotes: 0
Reputation: 106
import pymongo
from bson.objectid import ObjectId
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
db = myclient["test"]
comments_col = db["comments"]
doc = {
"post_body": "test",
"author": "test1",
"comments": [
{
"comment_body": "comment test",
"comment_author": "test2",
"replies": [
{
"reply_body": "reply test1",
"reply_author": "test3"
},
{
"reply_body": "reply test2",
"reply_author": "test2"
},
]
}
]
}
def insert(doc1):
id_comment = comments_col.insert(doc1)
return id_comment
def find(id_comment):
comment = comments_col.find_one({"_id": ObjectId(str(id_comment))})
return comment
if __name__ == "__main__":
id_comment = insert(doc)
comment = find(id_comment)
print("comments with replies : ", comment["comments"])
print("\n")
print("replies : ", comment["comments"][0]["replies"])
print("\n")
print("comment_author : ", comment["comments"][0]["comment_author"])
print("\n")
print("comment_body : ", comment["comments"][0]["comment_body"])
Upvotes: 1