user1816679
user1816679

Reputation: 855

How can I count all the comments in a tree?

I'm writing a threaded comment system and an trying to figure out a way of counting how many comments are below any given comment in the hierarchy. As of now each comment JSON object has a property called hasChildren which is an integer incremented every time someone replies to that comment. That means that hasChildren only keeps track of direct replies and not replies to replies.

Take this diagram:

OP--1.1--2.1--3.1
 |  
 1.2--2.2--3.2--4.1
      |    |
      |    4.2--5.1
      |
      3.3--4.3--5.2

How would I figure out how many comments are children, grandchildren, etc. of comment 1.2?

Upvotes: 0

Views: 166

Answers (2)

Jonathan Ong
Jonathan Ong

Reputation: 20315

the way i've done it is structure every comment like so:

{
  parent: _id,
  ancestors: [_id, _id]
}

where parent is the direct parent and ancestors are every parent comment above the ancestor chain. the first ancestor shouldn't be a comment (the post)

So suppose you have comment 1.2 that looks like so:

comment = {
  _id: _id,
  parent: OP._id,
  ancestors: [OP._id]
}

children:

db.comments.find({
  'parent': comment._id,
})

grandchildren:

db.comments.find({
  'ancestors.1': comment._id,
  'ancestors': {
    $size: 3
  }
})

all descendants:

db.comments.find({
  'ancestors.1': comment._id
})

then for indexes, you can do parent, ancestors.1, and, say, ancestors.6

Creating comments

here's a simplified example on how to create a comment

function Comment(parent) {
  this.parent = parent._id
  this.ancestors = (parent.ancestors || []).concat(parent._id)
}

var comment = new Comment(originalPost)
var child = new Comment(comment)
var grandchild = new Comment(child)

Upvotes: 0

Asya Kamsky
Asya Kamsky

Reputation: 42352

Consider changing your schema. There is a great example here which shows how you can store a hierarchy and how you can query it.

Upvotes: 2

Related Questions