I am trying analytics with mongodb , but i am very new at it although i got it working for 1 query i don't think its efficient one , here is my example of my dataset
{
_id: ObjectId("54442882fa2e117a55f3458b"),
analytic_num: 185,
createdAt: ISODate("2014-10-19T21:09:22.167Z"),
updatedAt: ISODate("2014-10-19T21:09:22.167Z"),
rawBrowser: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0",
gender: "male",
eventId: "accepted",
type: "member",
relationshipStatus: "Single",
ageRange: "18-25",
uid: "53f79ae6f158168161f04d27",
cid: "54370fa7498a776e1c065120",
education: ["high_school", "professional_degree"],
interestedIn: ["female"],
__v: 0
}
here is the query m trying
db.analytics.aggregate([{
$match: {
createdAt: {
$gte: new Date(2014, 9, 15),
$lt: new Date(2014, 9, 28)
}
}
}, {
$project: {
_id: 0,
minute: {
$minute: "$createdAt"
},
hour: {
$hour: "$createdAt"
}
}
}, {
$group: {
_id: {
minute: "$minute",
hour: "$hour"
},
hits: {
$sum: 1
}
}
}]);
here is the result i am getting
{ "_id" : { "minute" : 33, "hour" : 21 }, "hits" : 1 }
{ "_id" : { "minute" : 29, "hour" : 21 }, "hits" : 6 }
{ "_id" : { "minute" : 6, "hour" : 22 }, "hits" : 2 }
{ "_id" : { "minute" : 9, "hour" : 21 }, "hits" : 1 }
everything is fine but i only get hits for every minute of every hour , thats fine if i just want only hits
but i if need to find out hits by type or gender or ageRange i need to change $match
query, thats not efficient to run this query for all the attributes by changing $matvh
How can i get all the hits for type,gender, angRange in one query i want result like this
{ "_id" : { "minute" : 33, "hour" : 21 }, "hits" : 30, "member" :2 "single": 12 ,"male" :12 }
{ "_id" : { "minute" : 34, "hour" : 21 }, "hits" : 50, "member" :22 "single": 12 ,"male" :12 }
Pls help
thanks
You are looking for the $cond
operator. This allows you to evaluate a condition and then make a decision on whether this returns true|false
to which value you want to return. In this case, whether you want to add an increment to a $sum
operation or whether you don't:
db.analytics.aggregate([
{ "$match": {
"createdAt": {
"$gte": new Date(2014, 9, 15),
"$lt": new Date(2014, 9, 28)
}
}},
{ "$group": {
"_id": {
"minute": { "$minute": "$createdAt" },
"hour": { "$hour": "$createdAt" }
},
"hits": { "$sum": 1 },
"member": {
"$sum": {
"$cond": [
{ "$eq": [ "$type", "member" ] },
1,
0
]
}
},
"single": {
"$sum": {
"$cond": [
{ "$eq": [ "$relationshipStatus", "single" ] },
1,
0
]
}
},
"male": {
"$sum": {
"$cond": [
{ "$eq": [ "$gender", "male" ] },
1,
0
]
}
}
}}
]);
So the $cond
operator is basically a "ternary", or if..then..else
construct, which evaluates a condition and returns a value based on how that condition was determined, true|false
. You use it in this way to determine the value returned.
Be careful with date aggregation operators. Maybe what you want here is every minute of every hour, aggregated for all days within that range. But usually people just want the discrete time periods over each day, even by the minute.
Be careful what you ask for, you just might get it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.