couchdb/cloudant 时间序列查询
couchdb/cloudant time series querying
我有一个 cloudant 数据库,其中包含来自多个设备的一组度量。
每个设备发送许多测量值,但其中三个是有用的:温度、纬度和经度。
由于系统的设计,每个值都是一个单独的度量(我不能在插入时轻易加入温度、纬度和经度)并且在数据库中我有一组这样的度量:
{
"device": "foo",
"name": "temperature",
"date": <timestamp>,
"value": <value>
},
{
"device": "foo",
"name": "latitude",
"date": <timestamp>,
"value": <value>
},
{
"device": "foo",
"name": "longitude",
"date": <timestamp>,
"value": <value>
},
所以从概念上讲,我有 3 个时间序列。
我想提取每个时间序列的 latest 度量,理想情况下将它们按设备分组。
类似于:
{
device1: {
"temperature": {
date: <date>,
value: <value>
},
"latitude": {
date: <date>,
value: <value>
},
"longitude": {
date: <date>,
value: <value>
}
},
"device2": {
...
}
}
我不期待这种确切的语法,这只是我期待的数据集的想法。
我可以将位置度量结合在一起,但问题是一样的:如何将每个设备的最后 ts 条目组合在一起?
首先,我会使用这样的数据结构:
{
"type":"temperature",
"date":"1472528116698",
"value":"35",
"device":"device1"
}
类型属性可以是温度、纬度、经度。
那你需要一些看法。就个人而言,我更喜欢类型有一个_design文档,这样查询也更容易。
例如,对于温度,您会有这样的 _design 文档:
{
"_id": "_design/temperature",
"_rev": "8-91e594df623063ed3ad7111cde09eecb",
"language": "javascript",
"views": {
"byDevice": {
"map": "function(doc) {\n if ((doc.type + '').toLowerCase() === 'temperature' && doc.device)\n emit(doc.device);\n}\n"
},
"lastestByDevice": {
"map": "function(doc) {\n if ((doc.type + '').toLowerCase() === 'temperature' && doc.device && doc.value)\n emit(doc.device,doc.value);\n}\n",
"reduce": "function(keys, values, rereduce) {\n var max = Number.MIN_VALUE;\n for (var i = 0; i < values.length; i++) {\n var val = parseFloat(values[i]);\n if (val > max)\n max = val;\n }\n return max;\n}\n"
}
}
}
请求示例:
http://localhost:5984/db/_design/temperature/_view/latestByDevice?group_level=1&reduce=true
如果您使用具有 reduce 功能的最新设备,它会 return 每个设备的最大值。我们这个例子,你应该可以上手了。我不知道您如何接收和构建数据,但如果您更喜欢按设备对所有内容进行分组,这也是可能的。
我有一个 cloudant 数据库,其中包含来自多个设备的一组度量。 每个设备发送许多测量值,但其中三个是有用的:温度、纬度和经度。 由于系统的设计,每个值都是一个单独的度量(我不能在插入时轻易加入温度、纬度和经度)并且在数据库中我有一组这样的度量:
{
"device": "foo",
"name": "temperature",
"date": <timestamp>,
"value": <value>
},
{
"device": "foo",
"name": "latitude",
"date": <timestamp>,
"value": <value>
},
{
"device": "foo",
"name": "longitude",
"date": <timestamp>,
"value": <value>
},
所以从概念上讲,我有 3 个时间序列。 我想提取每个时间序列的 latest 度量,理想情况下将它们按设备分组。
类似于:
{
device1: {
"temperature": {
date: <date>,
value: <value>
},
"latitude": {
date: <date>,
value: <value>
},
"longitude": {
date: <date>,
value: <value>
}
},
"device2": {
...
}
}
我不期待这种确切的语法,这只是我期待的数据集的想法。
我可以将位置度量结合在一起,但问题是一样的:如何将每个设备的最后 ts 条目组合在一起?
首先,我会使用这样的数据结构:
{
"type":"temperature",
"date":"1472528116698",
"value":"35",
"device":"device1"
}
类型属性可以是温度、纬度、经度。
那你需要一些看法。就个人而言,我更喜欢类型有一个_design文档,这样查询也更容易。
例如,对于温度,您会有这样的 _design 文档:
{
"_id": "_design/temperature",
"_rev": "8-91e594df623063ed3ad7111cde09eecb",
"language": "javascript",
"views": {
"byDevice": {
"map": "function(doc) {\n if ((doc.type + '').toLowerCase() === 'temperature' && doc.device)\n emit(doc.device);\n}\n"
},
"lastestByDevice": {
"map": "function(doc) {\n if ((doc.type + '').toLowerCase() === 'temperature' && doc.device && doc.value)\n emit(doc.device,doc.value);\n}\n",
"reduce": "function(keys, values, rereduce) {\n var max = Number.MIN_VALUE;\n for (var i = 0; i < values.length; i++) {\n var val = parseFloat(values[i]);\n if (val > max)\n max = val;\n }\n return max;\n}\n"
}
}
}
请求示例:
http://localhost:5984/db/_design/temperature/_view/latestByDevice?group_level=1&reduce=true
如果您使用具有 reduce 功能的最新设备,它会 return 每个设备的最大值。我们这个例子,你应该可以上手了。我不知道您如何接收和构建数据,但如果您更喜欢按设备对所有内容进行分组,这也是可能的。