我有一个具有2cores,4GB Ram的VPS,并制作了一个简单的Express / NodeJS + Mongoose App,用于使用MQTT协议存储和检索来自IoT传感器的数据。 因此流程是这样的,服务器正在侦听MQTTT通道以获取值,并每1000条记录批量写入一次,每20000条记录创建一个新文档。代码的一部分是这个
let doc = {
updateOne: {
filter: { device: key, count: { $lt: 20001 } },
update: {
$push: { events: { values: item, when: time } },
$inc: { count: 1 },
},
upsert: true,
},
};
bulkOp.push(doc);
if (bulkOp.length == 100) {
Device.collection
.bulkWrite(bulkOp)
.then((bulkWriteOpResult) => {
var d = new Date(now());
console.log(d);
console.log("update OK");
console.log(JSON.stringify(bulkWriteOpResult, null, 2));
})
.catch((err) => {
console.log("update error");
console.log(JSON.stringify(err, null, 2));
});
bulkOp.length = 0;
}
到目前为止很好,几个小时后,我得到了20条记录和20000条记录。另外,我尝试使用CanvasJS进行API调用以通过分页获取这些数据,以使这些值成为图形视图。
这是1000个值的结果。响应来自以下查询:
exports.getDeviceSensor1 = (Model, popOptions) =>
catchAsync(async (req, res, next) => {
let query = Model.aggregate([
{ $match: { device: req.params.id } },
{ $unwind: "$events" }, //deconstruct the documents
{ $sort: { "events.when": -1 } },
{ $project: { _id: 0, "events.when": 1, "events.values.sensor1": 1 } },
{ $limit: 1000 },
]); //.limt(events: { $slice: 15 });
if (popOptions) query = query.populate(popOptions);
const doc = await query;
if (!doc) {
return next(new AppError("No document found with that ID", 404));
}
res.status(200).json({
status: "success",
results: doc.length,
doc,
});
});
尽管由于要获得所有40万个值并不切实际,所以我尝试进行如下分页:
await Model.aggregate([
{ $unwind: "$events" },
{
$match: {
device: req.params.id,
"events.when": {
$gte: new Date(2020, 04, 15).getTime(), // hardcoded will change as a query string
$lte: new Date(2020, 04, 16).getTime(), // hardcoded will change as a query string
},
},
},
{ $sort: { "events.when": 1 } },
{
$facet: {
metadata: [{ $count: "total" }, { $addFields: { page: pg } }],
data: [
{ $project: { _id: 0, "events.when": 1, "events.values.sensor1": 1 } },
{ $skip: skip },
{ $limit: limit },
],
},
},
])
.option({ allowDiskUse: true })
.exec((err, doc) => {
if (err) res.status(404).json({ err });
if (!doc) next(new AppError("No document found with that ID", 404));
res.status(200).json({
status: "successv2",
results: doc.length,
doc,
});
});
在查询字符串上有跳过和限制值的地方,我试图指定要获取值的日期。因此,我可以在另一个页面上请求500倍的URL,并获得创建图形所需的所有值。现在的问题是此查询需要大约3.5秒的响应时间,我不知道为什么。经过邮递员测试。
编辑: 数据库中的一条记录看起来像这样
_id: ObjectId("objecthash"),
device:"deviceId",
count:500,
events:
[
{
values: {
sensor1:"0.02",
sensor2:"0.08",
sensor3:"102"
},
when:1589797800614
},
....
]