Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting document with max size of inner array in MongoDB

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 } } } )
like image 252
javadee Avatar asked Apr 25 '14 21:04

javadee


People also ask

What is the maximum size of document in MongoDB?

The maximum size an individual document can be in MongoDB is 16MB with a nested depth of 100 levels. Edit: There is no max size for an individual MongoDB database.

Is there a way to query array fields with size greater than some specified value?

Yes, you can do that using $expr operator along with the $size operator. Here, we are using $expr operator to filter out all those documents which has size greater than or equal to 4.

What is $size in MongoDB?

$size. Counts and returns the total number of items in an array. $size has the following syntax: { $size: <expression> } The argument for $size can be any expression as long as it resolves to an array.


1 Answers

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 }
)
like image 91
Asya Kamsky Avatar answered Oct 14 '22 02:10

Asya Kamsky