MongoDB как получить количество комментариев + ответов - PullRequest
1 голос
/ 11 марта 2020

Итак, у меня есть эта структура в моем экземпляре MongoDB.

{
  "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"
        }
      ]
    }
  ]
}

И я хочу получить общее количество комментариев + ответов.

Поэтому мой желаемый результат должен быть

{
    "post_body": "test"
    "author": "test1",
    "comment_count": 3
}

Пока использование $project возвращает только общее количество комментариев. Я хочу получить общее количество комментариев + ответов

Ответы [ 2 ]

1 голос
/ 11 марта 2020
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"])
0 голосов
/ 11 марта 2020

Используя Агрегационный конвейер , мы можем получить желаемый результат

В приведенном ниже запросе используются этапы конвейера $ project , $ unwind и операторы конвейера $ size и $ 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"]}
    }
  }
])

Первая часть запроса агрегации использует $ project, и мы просто проецируем необходимые атрибуты на следующий этап, а также находим размер массива комментариев. Размер массива комментариев хранится во временном атрибуте comments_size

Во второй части используется $ unwind для разбиения вложенного массива в comments и comments.replies, массив comments не разматывается и comments.replies массив остается неизменным

Третья часть использует $ project для определения размера ответов и хранится во временном атрибуте replies_size

Четвертая и последняя часть снова использует $ project с $ сумма comments_size и replies_size для получения желаемого результата

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...