我的收藏如下:
[{
date: '20170721',
pageUrl: 'page1',
timing: [{ name: 'dns', duration: 1000 }, { name: 'tcp', duration: 2000 }]
}, {
date: '20170721',
pageUrl: 'page2',
timing: [{ name: 'dns', duration: 1001 }, { name: 'tcp', duration: 1800 }]
}, {
date: '20170722',
pageUrl: 'page1',
timing: [{ name: 'dns', duration: 1021 }, { name: 'tcp', duration: 1700 }]
}, {
date: '20170722',
pageUrl: 'page2',
timing: [{ name: 'dns', duration: 1101 }, { name: 'tcp', duration: 1850 }]
}]
我希望在给定的一段时间内给定页面的平均时间结果。
例如:我需要第1页的平均时间数据,从20170701 - 20170731开始
预期的输出应该是:
[{
_id: '20170701',
dns: <avgDuration>,
tcp: <avgDuration>
}, {
_id: '20170702',
dns: <avgDuration>,
tcp: <avgDuration>
},
...
]
我尝试过的是,它不起作用:
db.myCollection.aggregate([
{ $match: { 'pageUrl': targetPageUrl } },
{ $group: {
_id: '$date',
dns: { $avg: '$timing.0.duration' },
tcp: { $avg: '$timing.1.duration' }
},
...
])
有人可以帮忙吗?请
答案 0 :(得分:1)
如果这些职位总是“固定”,那么您可以使用$arrayElemAt
:
db.myCollection.aggregate([
{ '$match': { 'pageUrl': targetPageUrl } },
{ '$group': {
_id: '$date',
dns: { '$avg': { '$arrayElemAt': [ '$timing.duration', 0 ] } },
tcp: { '$avg': { '$arrayElemAt': [ '$timing.duration', 1 ] } }
}}
])
如果它们实际上没有修复,请使用$filter
获取匹配值:
db.myCollection.aggregate([
{ '$match': { 'pageUrl': targetPageUrl } },
{ '$group': {
_id: '$date',
dns: {
'$avg': {
'$avg': {
'$map': {
'input': {
'$filter': {
'input': '$timing',
'as': 't',
'cond': { '$eq': [ '$$t.name', 'dns' ] }
},
'as': 't',
'in': '$$t.duration'
}
}
}
},
tcp: {
'$avg': {
'$avg': {
'$map': {
'input': {
'$filter': {
'input': '$timing',
'as': 't',
'cond': { '$eq': [ '$$t.name', 'tcp' ] }
},
'as': 't',
'in': '$$t.duration'
}
}
}
}
}}
])
与$filter
一样,实际上可以在数组中使用“多个匹配”,并在模式中使用$avg
“减少”它们“both”一个累加器和一个以“数组”作为参数本身的东西。因此$avg
的“double”用法。
如果您认为自己真的必须,甚至可以使用$indexOfArray
:
db.myCollection.aggregate([
{ '$match': { 'pageUrl': targetPageUrl } },
{ '$group': {
_id: '$date',
dns: {
'$avg': {
'$arrayElemAt': [
'$timing.duration',
{ '$indexOfArray': [ '$timing.name', 'dns' ] }
]
}
},
tcp: {
'$avg': {
'$arrayElemAt': [
'$timing.duration',
{ '$indexOfArray': [ '$timing.name', 'tcp' ] }
]
}
}
}}
])