Ticket: User Report - Pipeline output shape

Seem to be getting correct results in Mongo shell with my pipeline:

{ "_id" : "roger_ashton-griffiths@gameofthron.es", "count" : [ { "count" : 909 } ] }
{ "_id" : "megan_richards@fakegmail.com", "count" : [ { "count" : 880 } ] }
{ "_id" : "bradley_brooks@fakegmail.com", "count" : [ { "count" : 880 } ] }
{ "_id" : "nathalie_emmanuel@gameofthron.es", "count" : [ { "count" : 874 } ] }
{ "_id" : "paul_kaye@gameofthron.es", "count" : [ { "count" : 870 } ] }

After $lookup stage also have $project and $sort. My problem is that $lookup wraps inner pipeline results in an array, on the other hand the test seems to expect a single key count. How can I unwrap from array? Tried index access at $project stage like this count: "$comments_count[0]" without success.

i can only say that following can be used to achieve the reports: $group, $match, $sort, $limit.
You just need to get the most commenters so avoid projections.

The HINT here is that in order to solve this ticket the implemented mostActiveCommenters() method does not require the $lookup stage at all.

The implemented method which you should not change ( with the exception of a small change related to "Read Concern ) actually acts directly on the comments collection:

const aggregateResult = await comments.aggregate(pipeline)

Nothing from any other collection is required, therefore you don’t need to and should not “join” here.

The actual implementation only requires you to implement three pipeline stages, at the minimum. And in fact this is what will be shown in the recommended answer once you have verified this ticket.

Basically:

  • Get the total sum of documents for a given grouping key.
  • Return those totals sorting with the largest sum appearing first to smallest in order.
  • Return the first 20 of those results only

Each one of those goals is achieved by a specific single aggregation pipeline stage.

6 Likes

Looked at the documentation for $group here:
(https://docs.mongodb.com/manual/reference/operator/aggregation/group/index.html)
The $sum accumulator operator applies to numeric fields, so that didn’t work. Also tried $push operator in combination with $size but that returns different count that doesn’t match the test number. Can you give additional hints? Or link to lecture for $group, can’t find it…

1 Like

Last time I checked, 1 is a numeric value.

Perhaps the SQL to Aggregation Mapping Chart in the core documentation might help you in understanding.

As the basic example directly from that page:

SELECT COUNT(*) AS count
FROM orders

Would be written in an aggregation pipeline as:

db.orders.aggregate( [
   {
     $group: {
        _id: null,
        count: { $sum: 1 }
     }
   }
] )

Keep in mind the question is basically asking you to do the same thing except to group by a certain key rather than just null, which is everything.

4 Likes

Thank you! All tests passing now. Was getting confused about the syntax.

Could be outside the scope of this course but was wondering why the $push in combination with $size would give different numbers.

1 Like

I cannot really think of how you would have even implemented that without seeing what code you wrote, and for various reasons it probably is not a good idea to include that code here, not the least of which being that I have seen far too many instances already were even incorrect code is widely being copied and attempted to be placed in as an answer.

You could always try asking the question on one of the various Q&A forum outside of this course. Still, if you choose to do this it would be appreciated if you changed the data structure sufficiently so it did not simply look like a “Question and Answer key” effectively enabling others to look up and rote copy from that source in order to pass this ticket. :slight_smile:


Side Note: I have always found it worthwhile to do post mortem responses on course material with better explanations of why certain answered points apply, but of course delievered after the assesment for tasks ( or indeed final exam ) are complete.

That will not be happening here as long as the decision is maintained that topics on the discussion forum are left open in between class iterations. This is currently the decision of how this forum is implemented.

It’s a real shame as open discussion after the fact is a good thing in order to help people understand or debate the WHY? of how answers are obtained. The consequences of NOT removing posts as the class for a course changes over is naturally that simply leaving “All the Answers” available for rote copy is not really acceptable, and clearly defeats the purpose of learning anything.

Yet as noted, this comes at the expense of actually educating the current class. Which is a real shame.

</endRant>

1 Like

Here is also a working fun operator,

    {$sortByCount: '$email'},     
    // same as
    // { $group: { _id: '$email', count: { $sum: 1 } } },
    // { $sort: { count: -1 } },
3 Likes

@neillunn thank you again :smiley: , your hints have been super helpful

const pipeline = [
{
$group: {
_id: comments.email,
count: { $sum: 1 }
}
}
]
i have used above pipeline. _id value returned is null.

1 Like

don’t forget to { $limit: 20 }.

const pipeline = [{ $sortByCount: "$email" },{ $limit: 20 }]

what will be the hierarchy of these 4 stages?