Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb: Count items by date then count unique items

I have a collection with items that shows user's visits to objects like this:

{"_id" : ObjectId("559d63ac2ea9e7b53ecc3275"),
"user" : {
    "id" : "65585",
    "cookie" : "spzSznyfDeeFMptiKZqqDg"
    },
"object_id" : "3",
"createddate" : ISODate("2015-07-08T17:53:48.209Z")}

I need to count them day-by-day grouping by object_id and in each day select unique users and count them. Now i have code that counts views of given object and selects distinct array of users viewed that object. Now i need to count this users. The code is:

db.objects.aggregate([
{"$match": {createddate: {$gt : ISODate("2015-07-01T00:00:00.000Z"), $lte : ISODate("2015-07-15T00:00:00.000Z")}} },
{"$match": {object_id: '1'}},
{"$group": {
    "_id": {
        "$subtract": [
            "$createddate",
            { "$mod": [
                { "$subtract": [ "$createddate", ISODate("1970-01-01T00:00:00.000Z") ] },
                1000 * 60 * 60 * 24
            ]}
        ]
    },
    "users": { "$addToSet": "$user"},
    "totalviews": { "$sum": 1 }
}},
{ "$sort": { "_id": -1 } }
])

Result is:

{
    "result" : [ 
        {
            "_id" : ISODate("2015-07-08T00:00:00.000Z"),
            "users" : [ 
                {
                    "id" : "65585",
                    "cookie" : "spzSznyfDeeFMptiKZqqDg"
                }, 
                {
                    "id" : null,
                    "cookie" : "spzSznyfDeeFMptiKZqqDg"
                }
            ],
            "totalviews" : 3
        }, 
        {
            "_id" : ISODate("2015-07-07T00:00:00.000Z"),
            "users" : [ 
                {
                    "id" : null,
                    "cookie" : "spzSznyfDeeFMptiKZqqDg"
                }, 
                {
                    "id" : "65585",
                    "cookie" : "spzSAAAAAAAAAAMptiKZqqDg"
                }, 
                {
                    "id" : "65585",
                    "cookie" : "spzSznyfDeeFMptiKZqqDg"
                }
            ],
            "totalviews" : 19
        }
    ],
    "ok" : 1
}

But i need result like:

{
    "result" : [ 
        {
            "_id" : ISODate("2015-07-08T00:00:00.000Z"),
            "userscount" : 2,
            "totalviews" : 3
        }, 
        {
            "_id" : ISODate("2015-07-07T00:00:00.000Z"),
            "userscount" : 3,
            "totalviews" : 19
        }
    ],
    "ok" : 1
}

Have no idea how to perform it in mongodb.

like image 616
aokozlov Avatar asked Jul 09 '15 17:07

aokozlov


1 Answers

Use the $size operator to get the total the number of items in the users array:

db.objects.aggregate([
    {"$match": {createddate: {$gt : ISODate("2015-07-01T00:00:00.000Z"), $lte : ISODate("2015-07-15T00:00:00.000Z")}} },
    {"$match": {object_id: '1'}},
    {"$group": {
        "_id": {
            "$subtract": [
                "$createddate",
                { "$mod": [
                    { "$subtract": [ "$createddate", ISODate("1970-01-01T00:00:00.000Z") ] },
                    1000 * 60 * 60 * 24
                ]}
            ]
        },
        "users": { "$addToSet": "$user"},
        "totalviews": { "$sum": 1 }
    }},
    { 
        "$project": {
            "totalviews": 1,
            "userscount": { "$size": "$users" }
        }
    },
    { "$sort": { "_id": -1 } }
])
like image 55
chridam Avatar answered Oct 18 '22 18:10

chridam