2

I want to implement a parent/child (Self Referencing) relationship for comments with its replies, Here's the code for the schema:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const BlogCommentSchema = new Schema({
  body: String,
  dateTime: { type: Date, default: Date.now },
  replies: [this]
});

const BlogComment = mongoose.model("blogComments", BlogCommentSchema);

module.exports = BlogComment;

What is the simplest way to get the number of comments or replies of a comment?

Any help would be appreciated.

Clarification: Here's an example of saved a document based on the schema:

{
  "replies": [
    {
      "replies": [
        {
          "replies": [],
          "_id": "5e558aa01f804205102b4a78",
          "body": "Comment 1.1.1",
          "dateTime": "2020-02-25T20:59:12.056Z"
        }
      ],
      "_id": "5e558aa01f804205102b4a79",
      "body": "Comment 1.1",
      "dateTime": "2020-02-25T20:59:12.057Z"
    },
    {
      "replies": [
        {
          "replies": [
            {
              "replies": [
                {
                  "replies": [
                    {
                      "replies": [],
                      "_id": "5e558aa01f804205102b4a7a",
                      "body": "Comment 1.2.1.1.1",
                      "dateTime": "2020-02-25T20:59:12.057Z"
                    }
                  ],
                  "_id": "5e558aa01f804205102b4a7b",
                  "body": "Comment 1.2.1.1.1",
                  "dateTime": "2020-02-25T20:59:12.057Z"
                }
              ],
              "_id": "5e558aa01f804205102b4a7c",
              "body": "Comment 1.2.1.1",
              "dateTime": "2020-02-25T20:59:12.057Z"
            }
          ],
          "_id": "5e558aa01f804205102b4a7d",
          "body": "Comment 1.2.1",
          "dateTime": "2020-02-25T20:59:12.058Z"
        }
      ],
      "_id": "5e558aa01f804205102b4a7e",
      "body": "Comment 1.2",
      "dateTime": "2020-02-25T20:59:12.058Z"
    }
  ],
  "_id": "5e558aa01f804205102b4a7f",
  "body": "Comment 1",
  "dateTime": "2020-02-25T20:59:12.058Z",
  "__v": 0
}

I need to get these numbers (total number of replies is 7, number of Comment 1.1 is 1, ...):

Comment 1 (count is 7)
  - Comment 1.1 (count 1)
    - Comment 1.1.1
  - Comment 1.2 (count 4)
    - Comment 1.2.1
      - Comment 1.2.1.1
        - Comment 1.2.1.1.1
          - Comment 1.2.1.1.1.1
Sirwan Afifi
  • 10,654
  • 14
  • 63
  • 110
  • It is not clear whether you want to get number of comments in top level or all comments hierarchically. Can you add sample documents and the expected document to the question? – SuleymanSah Feb 25 '20 at 20:08
  • @SuleymanSah Well I need both. I have just updated my question. – Sirwan Afifi Feb 25 '20 at 21:26
  • Does this answer your question? [Can a Mongo model self reference](https://stackoverflow.com/questions/24964914/can-a-mongo-model-self-reference) – Daniel W. Feb 25 '20 at 21:31
  • @DanielW. Thanks for sharing the link, I know Mongo can handle such relationship, my question is about querying a self-referenced schema not designing the schema. – Sirwan Afifi Feb 25 '20 at 21:33
  • 1
    @SirwanAfifi Then try this github issue pls: https://github.com/Automattic/mongoose/issues/5083 – Daniel W. Feb 25 '20 at 21:37

1 Answers1

2

I finally managed to get the result by adding a virtual type to my schema and use a recursive method to get the total number of replies:

const getRepliesCount = (comment, count = 0) => {
  if (comment.replies.length === 0) {
    return 1;
  }
  for (const reply of comment.replies) {
    count += getRepliesCount(reply, count);
  }
  return count;
};


BlogCommentSchema.virtual("total").get(function() {
  return getRepliesCount(this) + 1;
});

Although I was hoping there might be a built-in way or a proper way to do this using MongoDB/Mongoose.

Sirwan Afifi
  • 10,654
  • 14
  • 63
  • 110