5

Sample Mongo Document:

{
    "_id": "128374",
    "x": [
        {
            "i": "83847575",
            "y": [
                {
                    "i": "9389489283",
                    "t": "2014-04-11T20:46:57+0000"
                },
                {
                    "i": "9389489284",
                    "t": "2014-04-11T20:47:57+0000"
                }
            ]
        },
        {
            "i": "83847576",
            "y": [
                {
                    "i": "2382349385",
                    "t": "2014-01-15T23:43:29+0000"
                },
                {
                    "i": "9389489286",
                    "t": "2014-04-11T20:47:57+0000"
                },
                {
                    "i": "9389489286",
                    "t": "2014-04-11T20:49:57+0000"
                }
            ]
        }
    ]
}

How do you get max count of inner array 'y' per document? The problem I'm trying to solve is to get the record which has max number of 'y's. Thanks!

The following gives me the total count of 'y'.

db.coll.aggregate( 
{ "$unwind" : "$x" } , 
{ "$project" : { "x" : "$x" } } , 
{ "$unwind" : "$x.y" }, 
{ "$group" : { _id : null, number : { $sum : 1 } } } )
2
  • Why are you grouping on null? Commented Apr 25, 2014 at 23:11
  • how do you find size of x on this, as x is an array itself Commented Sep 15, 2015 at 6:25

3 Answers 3

4

If you want to find the document in the collection that has the most "y" elements in it the way to do that in aggregation framework would be like this:

db.coll.aggregate( {$unwind:"$x"},
                   {$project:{ysize:{$size:"$x.y"}}},
                   {$group:{_id:"$_id",numYs:{$sum:"$ysize"}}},
                   {$sort: {numYs:-1} },
                   {$limit: 1 }
)

This uses the $size operator (new in 2.6) to project size of the inner y arrays in each document, and the group adds them back up to calculate how many "y" elements each document has.

Adding sort and limit allows you to keep the top one, or top N.

This gives you the order by total number of y elements across the entire document. If you wanted to just know which document has the longest array y in it, it's even simpler, just take out the group and sort on ysize:

db.coll.aggregate( {$unwind:"$x"},
                   {$project:{ysize:{$size:"$x.y"}}},
                   {$sort: {ysize:-1} },
                   {$limit: 1 }
)
Sign up to request clarification or add additional context in comments.

1 Comment

when you upgrade to 2.6 the $size operator will eliminate the need to unwind the y array to then group it back just to count its size.
1

In order to count the inner elements you would need something to anchor on for a grouping. In this case you can use the i element that is at the same level as y:

db.collection.aggregate([
    { "$unwind" : "$x" }, 
    { "$unwind" : "$x.y" }, 
    { "$group" : { 
        "_id" : {
          "_id": "$_id",  
          "xi":"$x.i"
        },
        "number" : { "$sum" : 1 } 
    }},
    { "$sort": { "number": -1 }},
    { "$limit": 1 } 
])

So by compounding the grouping key with the document _id you can then match the document that has the largest inner value of y as a count by sorting that to the top.

Comments

0

Try this aggregation query.

db.collection.aggregate([
    {$unwind: '$x'},
    {$group: {_id: null, maxLengthOfYArray: {$max: {$size: '$x.y'}}}}
])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.