Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort by array length

Tags:

mongodb

How can I sort a query by the number of elements of an array field?

Let say I have records like

{
 title: '',
 author: '',
 votes: [id,id,id]
}

I would like to do sort by the length of the array votes

like image 320
nachoab Avatar asked May 30 '14 11:05

nachoab


People also ask

How do you sort an array by length?

To sort strings in an array based on length in JavaScript, call sort() method on this string array and pass a comparison function to sort() method, such that the comparison happens for the length of elements.

Does .length work on arrays?

The length variable is applicable to an array but not for string objects whereas the length() method is applicable for string objects but not for arrays.

Can sort () sort strings?

The sort() method is generic. It only expects the this value to have a length property and integer-keyed properties. Although strings are also array-like, this method is not suitable to be applied on them, as strings are immutable.

How do you sort data in an array?

Using the sort() Method In Java, Arrays is the class defined in the java. util package that provides sort() method to sort an array in ascending order. It uses Dual-Pivot Quicksort algorithm for sorting.


1 Answers

Use the aggregation framework with help from the $size operator from MongoDB 2.6 and upwards:

db.collection.aggregate([
    // Project with an array length
    { "$project": {
        "title": 1,
        "author": 1,
        "votes": 1,
        "length": { "$size": "$votes" }
    }},

    // Sort on the "length"
    { "$sort": { "length": -1 } },

    // Project if you really want
    { "$project": {
        "title": 1,
        "author": 1,
        "votes": 1,
    }}
])

Simple enough.

If you do not have a version 2.6 available you can still do this with a little more work:

db.collection.aggregate([
    // unwind the array
    { "$unwind": "$votes" },

    // Group back
    { "$group": {
        "_id": "$id",
        "title": { "$first": "$title" },
        "author": { "$first": "$author" },
        "votes": { "$push": "$votes" },
        "length": { "$sum": 1 }
    }},

    // Sort again
    { "$sort": { "length": -1 } },

    // Project if you want to
    { "$project": {
        "title": 1,
        "author": 1,
        "votes": 1,
    }}
])

That is pretty much it.

like image 184
Neil Lunn Avatar answered Sep 28 '22 08:09

Neil Lunn