在MongoDB博客的这篇文章中," Schema Design for Time Series Data in MongoDB"作者建议将多个时间序列值存储在单个文档中,作为基本时间戳的编号子项(即每分钟的文档,以值为数组的秒数)。
{
timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"),
type: “memory_used”,
values: {
0: 999999,
…
37: 1000000,
38: 1500000,
…
59: 2000000
}
}
建议的架构听起来不错,但是他们没有提到如何查询"值"如果您想知道最后一个样本何时发生,则需要使用字段名称。
您将如何构建查询以查找最新指标的时间(在值中组合timestamp_minute和最高字段名称)?
非常感谢!
答案 0 :(得分:0)
您只需查询分钟文档,然后在客户端上使用循环即可 确定已设置的时间戳:
doc = c.find(...)
var last = 0
for (var i=0; i<60; i++)
if (i in doc.values)
last = i
另一种更有效的方法是使用数组 而不是每秒样本的文档,然后使用 数组的长度,以确定已经有多少秒样本 存储:
doc = c.find(...)
last = doc.values.length - 1
答案 1 :(得分:0)
我在另一篇博客文章中找到了“可以查询字段名称”的答案,该帖子显示迭代密钥(正如Bruce建议的那样)只在MapReduce函数中执行ala:
var d = 0;
for (var key in this.values)
d = Math.max(d, parseInt(key));
对于MMS示例模式(在月份中为timestamp_minute交换,以及在下面标记为v的值数组中的天数),这里是生成最新指标日期的数据和查询:
db.metricdata.find();
/* 0 */
{
"_id" : ObjectId("5277e223be9974e8415f66f6"),
"month" : ISODate("2013-10-01T04:00:00.000Z"),
"type" : "ga-pv",
"v" : {
"10" : 57,
"11" : 49,
"12" : 91,
"13" : 27,
...
}
}
/* 1 */
{
"_id" : ObjectId("5277e223be9974e8415f66f7"),
"month" : ISODate("2013-11-01T04:00:00.000Z"),
"type" : "ga-pv",
"v" : {
"1" : 145,
"2" : 51,
"3" : 63,
"4" : 29
}
}
地图缩小功能:
db.metricdata.mapReduce(
function() {
var y = this.month.getFullYear();
var m = this.month.getMonth();
var d = 0;
// Here is where the field names used
for (var key in this.v)
d = Math.max(d, parseInt(key));
emit(this._id, new Date(y,m,d));
},
function(key, val)
{
return null;
},
{out: "idandlastday"}
).find().sort({ value:-1}).limit(1)
这会产生类似
的东西/* 0 */
{
"_id" : ObjectId("5277e223be9974e8415f66f7"),
"value" : ISODate("2013-11-04T05:00:00.000Z")
}