Reputation: 129
I'm trying to get a query where the output is grouped by date, but the next fields will be based on different date fields.
So, for the date 2018-11 (year-month), how many registers were, how many activations were, how many customers and how many cancels. But each register/activation/customer/cancel, has to be counted in the month when it happened.
My data is stored as follow:
{
"track" : {
"hasBeenCustomer" : true,
"hasActivated" : true,
"hasActivatedAt" : ISODate("2018-08-21T14:32:53.929Z"),
"hasBeenCustomerAt" : ISODate("2019-02-26T07:21:06Z"),
"hasRegisteredAt" : ISODate("2018-08-09T10:17:38.329Z"),
"hasCanceled" : true,
"hasCanceledAt" : ISODate("2019-04-29T13:56:04Z")
}
}
{
"track" : {
"hasBeenCustomer" : true,
"hasActivated" : true,
"hasActivatedAt" : ISODate("2018-08-26T15:04:58.854Z"),
"hasBeenCustomerAt" : ISODate("2018-11-24T10:37:14Z"),
"hasRegisteredAt" : ISODate("2018-08-25T11:12:36.309Z"),
"hasCanceled" : true,
"hasCanceledAt" : ISODate("2019-05-30T18:11:04Z")
}
}
{
"track" : {
"hasBeenCustomer" : true,
"hasActivated" : true,
"hasActivatedAt" : ISODate("2018-09-24T23:21:55.733Z"),
"hasBeenCustomerAt" : ISODate("2019-03-12T10:26:01Z"),
"hasRegisteredAt" : ISODate("2018-09-22T17:56:57.256Z"),
"hasCanceled" : true,
"hasCanceledAt" : ISODate("2019-04-12T10:22:03Z")
}
}
{
"track" : {
"hasBeenCustomer" : true,
"hasActivated" : true,
"hasActivatedAt" : ISODate("2018-10-18T15:08:15.351Z"),
"hasBeenCustomerAt" : ISODate("2018-12-22T21:37:01Z"),
"hasRegisteredAt" : ISODate("2018-10-16T03:54:16.056Z"),
"hasCanceled" : true,
"hasCanceledAt" : ISODate("2019-01-22T21:39:03Z")
}
}
I have tried this:
db.user.aggregate(
[
{
$match:
{
projectId : "00001"
}
},
{
"$project": {
"createDate": {
"$dateToString": {
"format": "%Y-%m",
"date": "$track.hasRegisteredAt"
}
},
activationAt: {
"$dateToString": {
"format": "%Y-%m",
"date": "$track.hasActivatedAt"
}
},
customerAt: {
"$dateToString": {
"format": "%Y-%m",
"date": "$track.hasBeenCustomerAt"
}
},
cancelAt: {
"$dateToString": {
"format": "%Y-%m",
"date": "$track.hasCanceledAt"
}
},
activations: {
"$sum": {
"$cond": [
{ "$eq": [ "$track.hasActivated", true ] },
1,
0
]
}
},
customers: {
"$sum": {
"$cond": [
{ "$eq": [ "$track.hasBeenCustomer", true ] },
1,
0
]
}
},
cancels: {
"$sum": {
"$cond": [{
"$and": [
{ "$eq": [ "$status", 3 ] },
{ "$eq": [ "$track.hasCanceled", true ] }
]},
1,
0
]
}
}
}
},
{
$group:
{
_id: "$createDate",
users: {$sum: 1},
activations: {$sum: "$activations"},
activationsM: {
"$sum": {
"$cond": [
{ "$eq": [ "$activationAt", "$createDate" ] },
1,
0
]
}
},
customers: {$sum: "$customers"},
customersM: {
"$sum": {
"$cond": [
{ "$eq": [ "$customerAt", "$createDate" ] },
1,
0
]
}
},
cancels: {$sum: "$cancels"},
cancelsM: {
"$sum": {
"$cond": [
{ "$eq": [ "$cancelAt", "$createDate" ] },
1,
0
]
}
},
}
},
{
$sort:
{
_id: 1
}
}
]
)
activationsM, customersM, cancelsM, are supposed to be the counting per month, independently from the _id field, but I have realized that, this query relieves in results matching the _id, and once it matches it, then it check the condintion. I need it to be sum, even if the _id doesn't match the hasActivatedAt, hasBeenCustomerAt, hasCanceledAt fields.
Hope I have explained it properly.
The desired output would be:
{ "_id" : "2018-06", "users" : 18, "activations" : 5, "activationsM" : 2, "customers" : 4, "customersM" : 0, "cancels" : 1, "cancelsM" : 0 }
{ "_id" : "2018-07", "users" : 78, "activations" : 39, "activationsM" : 31, "customers" : 11, "customersM" : 0, "cancels" : 7, "cancelsM" : 0 }
{ "_id" : "2018-08", "users" : 115, "activations" : 49, "activationsM" : 38, "customers" : 18, "customersM" : 0, "cancels" : 8, "cancelsM" : 0 }
Being fiedlM the total count for the correspondient field date and the _id date field.
Thanks.
Upvotes: 1
Views: 33
Reputation: 3185
Try as below:
db.collection.aggregate([
{
$facet: {
"TOTAL_ACTIVATION": [
{
$group: {
_id: "$track.hasActivated",
total: { "$sum": 1 },
"totalActiveCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasActivated", true ] },
1,
0
]}
},
"totalNonActiveCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasActivated", false ] },
1,
0
]}
},
}
}
],
"TOTAL_CUSTOMERS": [
{
$group: {
_id: "$track.hasBeenCustomer",
total: { "$sum": 1 },
"totalCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasBeenCustomer", true ] },
1,
0
]}
},
"totalNonCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasBeenCustomer", false ] },
1,
0
]}
},
}
}
],
"TOTAL_CANCELLED": [
{
$group: {
_id: "$track.hasCanceled",
total: { "$sum": 1 },
"totalCancelledCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasCanceled", true ] },
1,
0
]}
},
"totalNonCancelledCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasCanceled", false ] },
1,
0
]}
},
}
}
],
"MONTHLY_ACTIVATION" : [
{
$group: {
_id: {
year: { $year: "$track.hasActivatedAt" },
month: { $month: "$track.hasActivatedAt" }
},
totalThisMonth: { $sum : 1},
"totalActiveCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasActivated", true ] },
1,
0
]}
},
"totalNonActiveCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasActivated", false ] },
1,
0
]}
},
}
}
],
"MONTHLY_CUSTOMER" : [
{
$group: {
_id: {
year: { $year: "$track.hasBeenCustomerAt" },
month: { $month: "$track.hasBeenCustomerAt" }
},
totalThisMonth: { $sum : 1},
"totalCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasBeenCustomer", true ] },
1,
0
]}
},
"totalNonCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasBeenCustomer", false ] },
1,
0
]}
},
}
}
],
"MONTHLY_CANCELLED" : [
{
$group: {
_id: {
year: { $year: "$track.hasCanceledAt" },
month: { $month: "$track.hasCanceledAt" }
},
totalThisMonth: { $sum : 1},
"totalCancelledCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasCanceled", true ] },
1,
0
]}
},
"totalNonCancelledCustomer": {
"$sum": { "$cond": [
{ "$eq": [ "$track.hasCanceled", false ] },
1,
0
]}
},
}
}
]
}
}
])
Result of this will be as below:
{
"TOTAL_ACTIVATION" : [
{
"_id" : true,
"total" : 4,
"totalActiveCustomer" : 4,
"totalNonActiveCustomer" : 0
}
],
"TOTAL_CUSTOMERS" : [
{
"_id" : true,
"total" : 4,
"totalCustomer" : 4,
"totalNonCustomer" : 0
}
],
"TOTAL_CANCELLED" : [
{
"_id" : true,
"total" : 4,
"totalCancelledCustomer" : 4,
"totalNonCancelledCustomer" : 0
}
],
"MONTHLY_ACTIVATION" : [
{
"_id" : {
"year" : NumberInt(2018),
"month" : NumberInt(10)
},
"totalThisMonth" : 1,
"totalActiveCustomer" : 1,
"totalNonActiveCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2018),
"month" : NumberInt(9)
},
"totalThisMonth" : 1,
"totalActiveCustomer" : 1,
"totalNonActiveCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2018),
"month" : NumberInt(8)
},
"totalThisMonth" : 2,
"totalActiveCustomer" : 2,
"totalNonActiveCustomer" : 0
}
],
"MONTHLY_CUSTOMER" : [
{
"_id" : {
"year" : NumberInt(2018),
"month" : NumberInt(12)
},
"totalThisMonth" : 1,
"totalCustomer" : 1,
"totalNonCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2019),
"month" : NumberInt(3)
},
"totalThisMonth" : 1,
"totalCustomer" : 1,
"totalNonCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2018),
"month" : NumberInt(11)
},
"totalThisMonth" : 1,
"totalCustomer" : 1,
"totalNonCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2019),
"month" : NumberInt(2)
},
"totalThisMonth" : 1,
"totalCustomer" : 1,
"totalNonCustomer" : 0
}
],
"MONTHLY_CANCELLED" : [
{
"_id" : {
"year" : NumberInt(2019),
"month" : NumberInt(1)
},
"totalThisMonth" : 1,
"totalCancelledCustomer" : 1,
"totalNonCancelledCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2019),
"month" : NumberInt(5)
},
"totalThisMonth" : 1,
"totalCancelledCustomer" : 1,
"totalNonCancelledCustomer" : 0
},
{
"_id" : {
"year" : NumberInt(2019),
"month" : NumberInt(4)
},
"totalThisMonth" : 2,
"totalCancelledCustomer" : 2,
"totalNonCancelledCustomer" : 0
}
]
}
Upvotes: 1