我有一个递归的mongo文档结构,它是“事件”的层次结构:
{
"request": "open|casetype",
"datetime": ISODate("2013-10-10T23:06:37.000Z"),
"type": "pageload",
"totaltime": 4000,
"serverTime": 3000,
"clientTime": 1000,
"cpuTime" : "2000",
"externalTime" : "500",
"dbTime": "500",
"events":[
{
"type": "interaction",
"label": "interaction 1 - load",
"time": "2000",
"events" :[{
"type": "method",
"label": "test method",
"time": "1000",
"events" :[
{ "type": "dbquery", "sql": "select * from x", "time":"100"},
{ "type": "connector", "connectorName": "Google", "time":"200"},
{
"type":"method",
"label":"another method",
"time":800,
"events":[
{ "type": "dbquery", "sql": "select * from y", "time":"500"}
]
}
]
} ]
}
]
}
我希望能够运行查找和分组不同类型事件的查询。例如。查找给定dbquery或连接器的平均时间。通过connectorName对连接器进行分组并获取计数等
使用以下(我在StackOverflow上找到),我可以在文档中的任何位置找到type =“X”的完整文档:
db.pageloads.find(
function () {
var findKey = "type",
findVal = "dbquery";
function inspectObj(doc) {
return Object.keys(doc).some(function(key) {
if ( typeof(doc[key]) == "object" ) {
return inspectObj(doc[key]);
} else {
return ( key == findKey && doc[key] == findVal );
}
});
}
return inspectObj(this);
}
)
然而,我真正想要的只是包含映射的子文档,然后我可以对其进行聚合。我不确定此时我的问题是查找本身还是文档结构之一。
答案 0 :(得分:0)
作为变种,您可以使用自定义查询功能。
这是查找平均时间的示例。 将下面的代码放在 query.js 文件中:
(function() {
var cursor = db.pageloads.find(),
result = [],
findKey = 'type',
findVal = 'dbquery',
findParam = 'time';
function average(data) {
return sum(data) / data.length;
}
function sum(data) {
var sum = 0;
for (var i = 0; i < data.length; i++) {
sum += parseInt(data[i], 10);
}
return sum;
}
while (cursor.hasNext()) {
function filter(current) {
for (var item in current) {
if (typeof(current[item].events) === 'object') {
var next = current[item].events;
delete current[item].events;
}
if (typeof(current[item][findKey]) !== 'undefined' && current[item][findKey] === findVal) {
result.push(current[item][findParam]);
}
}
if (typeof(next) !== 'undefined') {
filter(next);
};
}
filter(cursor.next().events);
};
return average(result); // You can use sum or other function
})();
并运行:
mongo your_database < query.js --quiet
您可以通过更改参数和内部子功能来调整聚合逻辑。
当然,这不是一个干净的解决方案,但它总比没有好。