我有以下文档结构:
{
"_id" : ObjectId("5a16b7cf930a1e000465d1c5"),
"trackerId" : ObjectId("5a16b7b8930a1e000465d1c1"),
"trackingEvents" : [
{
"type" : "checkin",
"timestamp" : ISODate("2017-11-23T11:57:43.710Z"),
},
{
"type" : "connectivity",
"timestamp" : ISODate("2017-11-23T11:57:47.011Z"),
},
{
"type" : "power",
"timestamp" : ISODate("2017-11-23T11:57:47.036Z"),
}
]
}
我想设置一个查询来计算所有trackingEvents
发生的< "type":"power"
trackingEvents
的数量,其中db.getCollection('trackerEvents').aggregate( [
{$unwind: "$trackingEvents"},
{$match:
{
"trackingEvents.type": "power",
"trackingEvents.timestamp": {
"$gt": {
"$humanTime": "1 month ago" //redash operator
}
}
}
},
{
"$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$trackingEvents.timestamp"
}
},
count: {$sum: 1}
}
},
,
{ $sort : { "_id":1 } }
])
按日分组1个月前。并且以下查询工作正常,除了它不够快的事实:
$match
但是,此查询未通过代码审核,因为我的同事建议交换$unwind
和$match
运算符,以便$unwind
在$match
之前进行,以提高性能的查询。如果我交换这两个运算符,我会得到不同的结果,有人可以建议在$unwind
之前如何对{{1}}文档的数组元素进行建议吗?
谢谢!
答案 0 :(得分:0)
您可以使用 $match
运算符来提前过滤文档,然后在 {{之前在数组级别 $filter
进行过滤3}} 强>:
var oneMonthAgo = new Date();
oneMonthAgo.setMonth(oneMonthAgo.getMonth()-1);
// var oneMonthAgo = moment().subtract(1, "months").unix();
db.getCollection('trackerEvents').aggregate([
{
"$match": {
"trackingEvents.type": "power",
"trackingEvents.timestamp": { "$gt": oneMonthAgo }
}
},
{
"$project": {
"trackingEvents": {
"$filter": {
"input": "$trackingEvents",
"as": "event",
"cond": {
"$and": [
{ "$eq": ["$$event.type", "power"] },
{ "$gt": ["$$event.timestamp", oneMonthAgo] }
]
}
}
}
}
},
{ "$unwind": "$trackingEvents" },
{
"$group": {
"_id": {
"$dateToString": {
"format": "%Y-%m-%d",
"date": "$trackingEvents.timestamp"
}
},
"count": { "$sum": 1}
}
},
{ "$sort": { "_id": 1 } }
]);