使用Node.js查询MongoDB近1分钟插入文档合并后写入新集合的实现方法
实现方案
1. 区间查询语句编写
你已经完成了时间窗口的计算,筛选指定区间内的文档有两种写法,两种效果完全一致:
// 显式使用$and的写法 const query = { $and: [ { timeStamp: { $gte: lastMinuteStarted } }, { timeStamp: { $lt: lastMinuteEnded } } ] }; // 更简洁的隐式AND写法(MongoDB默认多个字段条件为AND关系) const simpleQuery = { timeStamp: { $gte: lastMinuteStarted, $lt: lastMinuteEnded } };
说明:这里使用$lt而非$lte是为了避免边界时间戳的文档被重复统计,刚好等于lastMinuteEnded的文档属于下一分钟的时间窗口
2. 完整实现流程
- 先安装MongoDB官方Node.js驱动:
npm install mongodb - 完整功能代码示例如下:
const { MongoClient } = require('mongodb'); // 基础配置 const mongoUri = '替换为你的MongoDB连接地址'; const sourceCollection = 'Prices'; // 源集合名 const targetCollection = 'MinuteAggregate'; // 目标聚合集合名 async function aggregateLastMinuteData() { const client = new MongoClient(mongoUri); try { await client.connect(); const db = client.db(); // 不传库名则默认使用连接字符串指定的数据库 // 计算最近1分钟时间窗口 const currentTimeStamp = Date.now(); const currentMilliSeconds = currentTimeStamp % 60000; const lastMinuteStarted = currentTimeStamp - currentMilliSeconds - 60000; const lastMinuteEnded = currentTimeStamp - currentMilliSeconds; // 查询匹配的所有文档 const matchedDocs = await db.collection(sourceCollection) .find({ timeStamp: { $gte: lastMinuteStarted, $lt: lastMinuteEnded } }) .toArray(); // 无匹配数据时可自行选择是否插入空记录,示例中直接跳过 if (matchedDocs.length === 0) { console.log('最近1分钟无新增数据,跳过聚合'); return; } // 组装目标格式的聚合文档 const aggregatedDoc = { minuteStarted: lastMinuteStarted, minuteEnded: lastMinuteEnded, allDataofthisminute: matchedDocs }; // 插入到目标集合 const insertRes = await db.collection(targetCollection).insertOne(aggregatedDoc); console.log('聚合完成,生成新文档ID:', insertRes.insertedId); } catch (err) { console.error('执行出错:', err); } finally { await client.close(); } } // 执行函数 aggregateLastMinuteData();
3. 注意事项
- 建议给源集合
Prices的timeStamp字段添加索引,避免数据量大时查询性能过低,建索引语句:db.Prices.createIndex({timeStamp: 1}) - 如果需要定时每分钟自动执行,可以搭配
node-cron等定时任务库,设置每整分钟触发一次即可 - 如果你使用的是Mongoose作为ODM,查询语法完全一致,只需要替换为对应Model调用
find方法即可
内容的提问来源于stack exchange,提问作者Jahanzaib Khan
相关产品推荐
相关产品推荐

