使用 MongoDB Aggregator Framework 格式化与 chartjs scatter 匹配的数据
Using MongoDB Aggregator Framework to format data that match with chartjs scatter
我是 MongoDB 中使用聚合器的新手,我想知道是否有一种方法可以在 MongoDB 级别格式化数据以准备使用 ChartJs scatter 绘图的结果。
所以我有一个时间序列数据集(我不确定这是存储时间序列数据的最佳方式,所以欢迎任何建议),如下所示:
{
"dataset_id" : "850919c9-30e4-46f1-b962-e6b16cd30c60",
"time_stamp" : 1600624542,
"series" : [
{
"name" : "serie_0",
"value" : 935.0
},
{
"name" : "serie_1",
"value" : 780.0
},
...
{
"name" : "serie_n",
"value" : <value_n>
},
]
}
但是对于 ChartJS,我需要这样的格式:
[
{
label: '<series_0_name>',
data: [
{x: <timestamp>, y: <value>},
...
{x: <timestamp>, y: <value>},
]
},
...
{
label: '<series_n_name>',
data: [
{x: <timestamp>, y: <value>},
...
{x: <timestamp>, y: <value>},
]
},
]
此刻为了存档,我正在使用这个 python 代码(我正在使用 PyMongo):
def dataset_format(dataset_id, sample_size):
match = {"$match": {"dataset_id": str(dataset_id)}}
sample = {"$sample": {"size": sample_size}}
unwind = {"$unwind": {"path": "$series"}}
stages = [match, sample, unwind]
pool = DB_POOL_COLLECTION.aggregate(stages)
values = [
(record["series"]["name"], record["time_stamp"], record["series"]["value"])
for record in pool
]
data = [
{"label": d, "data": [{"x": v[1], "y": v[2]} for v in values if v[0] == d]}
for d in set(name[0] for name in values)
]
return data
但考虑到性能,我认为将此 python 格式化代码移动到 MongoDb 端会提高查询的性能。正如我之前所说,这个项目是从头开始的,所以我愿意接受有关我的数据库文档样式的建议,考虑到我需要良好的阅读性能,但我现在不关心写入性能。
我用这种方法做到了,我仍然不确定是否是最有效的方法,但现在的性能非常好
def dataset_info(dataset_id, sample_size):
stages = [
{"$match": {"dataset_id": str(dataset_id)}},
{"$sample": {"size": sample_size}},
{"$sort": {"time_stamp": 1}},
{"$unwind": {"path": "$series"}},
{
"$project": {
"label": "$series.name",
"data": {
"x": {"$multiply": ["$time_stamp", 1000]},
"y": "$series.value",
},
}
},
{"$group": {"_id": "$label", "data": {"$push": "$data"}}},
{
"$project": {
"_id": 0,
"label": "$_id",
"data": 1,
"showLine": {"$toBool": 1},
"fill": {"$toBool": 0},
}
},
{"$sort": {"label": 1}},
]
data = DB_POOL_COLLECTION.aggregate(stages)
return list(data)
此 returns 数据结构已准备好用于 ChartJS,例如:
[
{
label: '<series_0_name>',
showLine: true,
fill: false,
data: [
{x: <timestamp in ms>, y: <value>},
...
{x: <timestamp in ms>, y: <value>},
]
},
...
{
label: '<series_n_name>',
showLine: true,
fill: false,
data: [
{x: <timestamp in ms>, y: <value>},
...
{x: <timestamp in ms>, y: <value>},
]
},
]
我是 MongoDB 中使用聚合器的新手,我想知道是否有一种方法可以在 MongoDB 级别格式化数据以准备使用 ChartJs scatter 绘图的结果。
所以我有一个时间序列数据集(我不确定这是存储时间序列数据的最佳方式,所以欢迎任何建议),如下所示:
{
"dataset_id" : "850919c9-30e4-46f1-b962-e6b16cd30c60",
"time_stamp" : 1600624542,
"series" : [
{
"name" : "serie_0",
"value" : 935.0
},
{
"name" : "serie_1",
"value" : 780.0
},
...
{
"name" : "serie_n",
"value" : <value_n>
},
]
}
但是对于 ChartJS,我需要这样的格式:
[
{
label: '<series_0_name>',
data: [
{x: <timestamp>, y: <value>},
...
{x: <timestamp>, y: <value>},
]
},
...
{
label: '<series_n_name>',
data: [
{x: <timestamp>, y: <value>},
...
{x: <timestamp>, y: <value>},
]
},
]
此刻为了存档,我正在使用这个 python 代码(我正在使用 PyMongo):
def dataset_format(dataset_id, sample_size):
match = {"$match": {"dataset_id": str(dataset_id)}}
sample = {"$sample": {"size": sample_size}}
unwind = {"$unwind": {"path": "$series"}}
stages = [match, sample, unwind]
pool = DB_POOL_COLLECTION.aggregate(stages)
values = [
(record["series"]["name"], record["time_stamp"], record["series"]["value"])
for record in pool
]
data = [
{"label": d, "data": [{"x": v[1], "y": v[2]} for v in values if v[0] == d]}
for d in set(name[0] for name in values)
]
return data
但考虑到性能,我认为将此 python 格式化代码移动到 MongoDb 端会提高查询的性能。正如我之前所说,这个项目是从头开始的,所以我愿意接受有关我的数据库文档样式的建议,考虑到我需要良好的阅读性能,但我现在不关心写入性能。
我用这种方法做到了,我仍然不确定是否是最有效的方法,但现在的性能非常好
def dataset_info(dataset_id, sample_size):
stages = [
{"$match": {"dataset_id": str(dataset_id)}},
{"$sample": {"size": sample_size}},
{"$sort": {"time_stamp": 1}},
{"$unwind": {"path": "$series"}},
{
"$project": {
"label": "$series.name",
"data": {
"x": {"$multiply": ["$time_stamp", 1000]},
"y": "$series.value",
},
}
},
{"$group": {"_id": "$label", "data": {"$push": "$data"}}},
{
"$project": {
"_id": 0,
"label": "$_id",
"data": 1,
"showLine": {"$toBool": 1},
"fill": {"$toBool": 0},
}
},
{"$sort": {"label": 1}},
]
data = DB_POOL_COLLECTION.aggregate(stages)
return list(data)
此 returns 数据结构已准备好用于 ChartJS,例如:
[
{
label: '<series_0_name>',
showLine: true,
fill: false,
data: [
{x: <timestamp in ms>, y: <value>},
...
{x: <timestamp in ms>, y: <value>},
]
},
...
{
label: '<series_n_name>',
showLine: true,
fill: false,
data: [
{x: <timestamp in ms>, y: <value>},
...
{x: <timestamp in ms>, y: <value>},
]
},
]