JavaScript $sum from documents and subdocuments group by “$author” (MongoDB)

This is my collection:

{
        "_id" : 10926400,
        "votes": 131,
        "author": "Jesse",
        "comments" : [
                {
                        "id" : 1,
                        "votes": 31,
                        "author": "Mirek"
                },
                {
                        "id": 2,
                        "votes": 13,
                        "author": "Leszke"
                }
        ]
},
{
        "_id" : 10926401,
        "votes": 75,
        "author": "Mirek",
        "comments" : [
                {
                        "id" : 1,
                        "votes": 17,
                        "author": "Jesse"
                },
                {
                        "id": 2,
                        "votes": 29,
                        "author": "Mirek"
                }
        ]
}

And I want $sum values of votes and comments.votes of each author

expected output(sort $votes: -1):

"Mirek" total votes: 31 + 75 + 29 = 135

"Jesse" total votes: 131 + 17 = 148

"Leszke total votes: 13
Answer:1

Not immediately visible but possible. What you need to do here is combine your top level document with the array of comments without duplicating it. Here's an approach to first join the content as two arrays into a singular array, then $unwind to group the content:

db.collection.aggregate([
    { "$group": {
        "_id": "$_id",
        "author": { 
            "$addToSet": {
                "id": "$_id",
                "author": "$author",
                "votes": "$votes"
            }
        },
        "comments": { "$first": "$comments" }
    }},
    { "$project": {
        "combined": { "$setUnion": [ "$author", "$comments" ] }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Which gives the output:

{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }

Even as skipping the first $group stage and making a combined array a different way:

db.collection.aggregate([
    { "$project": {
        "combined": { 
            "$setUnion": [
                { "$map": {
                    "input": { "$literal": ["A"] },
                    "as": "el",
                    "in": { 
                        "author": "$author",
                        "votes": "$votes"
                    }
                }},
                "$comments"
            ] 
        }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Those use operators such as $setUnion and even $map which were introduced as of MongoDB 2.6. This makes it simplier, but it can still be done in earlier versions lacking those operators, following much the same principles:

db.collection.aggregate([
    { "$project": {
        "author": 1,
        "votes": 1,
        "comments": 1,
        "type": { "$const": ["A","B"] }
    }},
    { "$unwind": "$type" },
    { "$unwind": "$comments" },
    { "$group": { 
        "_id": {
          "$cond": [
              { "$eq": [ "$type", "A" ] },
              { 
                  "id": "$_id", 
                  "author": "$author",
                  "votes": "$votes"
              },
              "$comments"
          ]
        }
    }},
    { "$group": {
        "_id": "$_id.author",
        "votes": { "$sum": "$_id.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

The $const is undocumented but present in all versions of MongoDB where the aggregation framework is present ( from 2.2 ). MongoDB 2.6 Introduced $literal which essentially links to the same underlying code. It's been used in two cases here to either provide a template element for an array, or as introducing an array to unwind in order to provide a "binary choice" between two actions.

Answer:2

I've just figured out that object in React's state that have multiple children cannot be rendered easily. In my example I have component which speaks with third-party API through AJAX: var Component ...

I've just figured out that object in React's state that have multiple children cannot be rendered easily. In my example I have component which speaks with third-party API through AJAX: var Component ...

  1. react deep object comparison
  2. react deep object compare
  3. react object deep copy
  4. react object deep merge
  5. react setstate deep object
  6. react deep clone object
  7. react state deep object
  8. react deep clone state object
  9. react js deep copy object

I'm working on an app that starts a Google Hangout On Air. We do this programmatically using Javascript and the Google+ Hangouts API. We've successfully created the button and when you click it, it ...

I'm working on an app that starts a Google Hangout On Air. We do this programmatically using Javascript and the Google+ Hangouts API. We've successfully created the button and when you click it, it ...

  1. google hangouts does not ring
  2. google hangouts does not work
  3. google hangouts how does it work
  4. google hangouts what does active mean
  5. google hangouts camera doesn't work
  6. what does google hangouts do
  7. does google hangouts cost money
  8. does google hangouts still work
  9. does google hangouts use data
  10. does google hangouts notify screenshots
  11. does google hangouts work internationally
  12. does google hangouts have screen sharing
  13. does google hangouts work in uae
  14. does google hangouts charge for calls
  15. does google hangouts work in dubai
  16. does google hangouts record calls
  17. does google hangouts work in china
  18. does google hangouts show your location
  19. does google hangouts have video chat
  20. does google hangouts use wifi

I have a base template: <template name="ApplicationLayout"> {{> yield}} </template> and I route templates into it using Iron Router, like so: Router.configure({ layoutTemplate: ...

I have a base template: <template name="ApplicationLayout"> {{> yield}} </template> and I route templates into it using Iron Router, like so: Router.configure({ layoutTemplate: ...

Hi there my code is quite simple but Id like for the design purposes to keep everything neat , at the moment Im pulling all the description which is like Some could be huge others can be quite small , ...

Hi there my code is quite simple but Id like for the design purposes to keep everything neat , at the moment Im pulling all the description which is like Some could be huge others can be quite small , ...

  1. read more from database