want_to_be_calm
want_to_be_calm

Reputation: 1627

How to get single document with group that have duplicate key in MongoDB

I have an aggregate as follows:

[
    {
        "$project" : {
                "country_code" : "$country_code",
                "event" : "$event",
                "user_id" : "$user_id",
                "os" : "$os",
                "register_time" : "$register_time",
                "channel" : "$channel"
        }
    },
    {
        "$match" : {
                "channel" : "000001",
                "register_time" : {
                    "$gt" : ISODate("2016-06-01T00:00:00Z"),
                    "$lt" : ISODate("2016-06-30T23:59:00Z")
                },
                "event" : "Register_with_number"
        }
    },
    {
        "$group" : {
                "_id" : {
                    "country_code" : "$country_code",
                    "user_id" : "$user_id",
                    "os" : "$os",
                    "channel" : "$channel",
                    "register_time" : "$register_time"
                },
                "count" : {
                    "$sum" : 1
                }
        }
    }
]

And the result is as follows: you can for the country_code with IN, two records are having same user_id but different register_time, how can I get only one record if the user_id is same.

{ "_id" : { "country_code" : "US", "user_id" : "d2a0fe91", "os" : "Android", "channel" : "000001", "register_time" : ISODate("2016-06-30T22:47:43Z") }, "count" : 1 }    
{ "_id" : { "country_code" : "US", "user_id" : "77911591", "os" : "Android", "channel" : "000001", "register_time" : ISODate("2016-06-30T19:47:21Z") }, "count" : 1 }
{ "_id" : { "country_code" : "IN", "user_id" : "1b72fd12", "os" : "Android", "channel" : "000001", "register_time" : ISODate("2016-06-30T19:17:28Z") }, "count" : 1 }
{ "_id" : { "country_code" : "IN", "user_id" : "1b72fd12", "os" : "Android", "channel" : "000001", "register_time" : ISODate("2016-06-30T19:15:13Z") }, "count" : 1 }
{ "_id" : { "country_code" : "ID", "user_id" : "045f1637", "os" : "Android", "channel" : "000001", "register_time" : ISODate("2016-06-30T19:02:19Z") }, "count" : 1 }

Upvotes: 1

Views: 161

Answers (1)

DAXaholic
DAXaholic

Reputation: 35348

There are several solutions, as you did not mention what the document should look like when there are several documents with the same user but different register_time.
The following changes your last $group stage so that it keeps an array of the register_time values with $push or - if you just need one - keeps any of them with $first. Note that when you sort your pipeline by register_time, you could use $first / $last to keep the first / last register_time per user which is perhaps your desired result.

"$group" : {
        "_id" : {
            "country_code" : "$country_code",
            "user_id" : "$user_id",
            "os" : "$os",
            "channel" : "$channel",
        },
        "register_times" : {
            $push: "$register_time"
        },
        "any_register_time" : {
            $first: "$register_time"
        },                
        "count" : {
            "$sum" : 1
        }
}

Upvotes: 1

Related Questions