1

I have data structure from mongoDb v 3.2 I will try make sorting date by month and sorting within statistic array through aggregation-framework

Source data:

   "monthStart" : "2015-11",
"monthEnd" : "2015-11",
"date" : ISODate("2016-03-09T09:06:58Z"),
"statistic" : [
    {
        "name" : "site1.com",
        "ga" : "99999",
        "data" : {
            "desktop" : {
                "users" : NumberLong(25),
                "pageviews" : NumberLong(56789),
            }
        }
    },
    {
        "name" : "site2.com",
        "ga" : "102",
        "data" : {
            "desktop" : {
                "users" : NumberLong(21),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
    {
        "name" : "site3.com",
        "ga" : "103",
        "data" : {
            "desktop" : {
                "users" : NumberLong(103),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
{
"monthStart" : "2015-12",
"monthEnd" : "2015-12",
"date" : ISODate("2016-03-09T09:08:39Z"),
"statistic" : [
    {
        "name" : "site1.com",
        "ga" : "9999",
        "data" : {
            "desktop" : {
                "users" : NumberLong(88),
                "pageviews" : NumberLong(83838),
            },
        }
    },
    {
        "name" : "site2.com",
        "ga" : "8888",
        "data" : {
            "desktop" : {
                "users" : NumberLong(75),
                "pageviews" : NumberLong(77777777),
            },

        }
    },
    {
        "name" : "site3.com",
        "ga" : "103",
        "data" : {
            "desktop" : {
                "users" : NumberLong(25),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
    }
]

How I can get structure sorting within array statistic?

Expected result :

    "monthStart" : "2015-11",
"monthEnd" : "2015-11",
"date" : ISODate("2016-03-09T09:06:58Z"),
"statistic" : [
    {
        "name" : "site3.com",
        "ga" : "103",
        "data" : {
            "desktop" : {
                "users" : NumberLong(103),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
            {
        "name" : "site2.com",
        "ga" : "102",
        "data" : {
            "desktop" : {
                "users" : NumberLong(21),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
    {
        "name" : "site1.com",
        "ga" : "99999",
        "data" : {
            "desktop" : {
                "users" : NumberLong(25),
                "pageviews" : NumberLong(56789),
            }
        }
    },

{
"monthStart" : "2015-12",
"monthEnd" : "2015-12",
"date" : ISODate("2016-03-09T09:08:39Z"),
"statistic" : [
        {
        "name" : "site3.com",
        "ga" : "103",
        "data" : {
            "desktop" : {
                "users" : NumberLong(201),
                "pageviews" : NumberLong(9399393),
            }
        }
    },
    {
        "name" : "site1.com",
        "ga" : "9999",
        "data" : {
            "desktop" : {
                "users" : NumberLong(88),
                "pageviews" : NumberLong(83838),
            },
        }
    },
    {
        "name" : "site2.com",
        "ga" : "8888",
        "data" : {
            "desktop" : {
                "users" : NumberLong(75),
                "pageviews" : NumberLong(77777777),
            },

        }
    },

    }
]

I tried make, but it is didn't work:

     db.TrafficStatistic.aggregate([
{ "$unwind": "$statistic" },
{ "$sort": { "statistic.data.desktop.users": 1 } } ])
Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
itcoder
  • 187
  • 1
  • 5
  • 17

1 Answers1

4

I see the problem. People are searching for and finding this stackoverflow answer:

how to sort array inside collection record in mongoDB

It's wrong, since it never "reconstructs" the array.

You do that with $group and $push, and since you are grouping you will want $first for the other fields in the document you want:

db.TrafficStatistic.aggregate([
   { "$unwind": "$statistic" },
   { "$sort": { "_id": 1, "statistic.data.desktop.users": 1 } },
   { "$group": {
       "_id": "$_id",
       "monthStart" : { "$first": "$monthStart" },
       "monthEnd" : { "$first": "$monthEnd" },
       "date" : { "$first": "$date" },
       "statistic": { "$push": "$statistic" }
   }}
])

Note also the $sort is applied to both the "_id" and the other field to sort. This is so the sorting is applied per document and is important when the document details are put back together in $group.

Now the document looks the same as it did, but this time the array members are sorted.

Community
  • 1
  • 1
Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
  • Thanks it work,but you can help me? how can I make do sort by priority field: "monthStart" > result "2015-01", "2015-02", "2015-03".... ? – itcoder Mar 09 '16 at 11:38
  • @itcoder Sorry but I have no idea what you mean. You should [Ask a New Question](http://stackoverflow.com/questions/ask) anyway as it is the best way to make what you are asking clear, as well as that is generally how things work here. Ask one question, get one answer. If you have other questions then post them. – Blakes Seven Mar 09 '16 at 11:43