使用NodeJS在MongoDB中计算平均值

时间:2020-07-01 08:43:03

标签: javascript node.js mongodb

我有一个MongoDB,它每30分钟间隔存储一次数据。我想计算一个特定领域的平均值。由于数据每30分钟就会保存到数据库一次,因此我也需要计算所有新传入的数据。

问题:是否可以使用MongoDB + NodeJS以及如何每30分钟计算一次"Volume"的平均值?

我一直在寻找 MongoDB aggregation framework ,但是可以自动化吗?因为我也需要每30分钟查看一次平均值。

这是该文档在MongoDB中的外观,我需要计算“体积”字段的平均值 enter image description here

从Binance API接收数据的CODE部分。

const getBTCData = async symbol => { //make this function accept the current symbol
    //async/await lets us write this much nicer and with less nested indents
    let data = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=30m&limit=1`).then(res => res.json());
    const btcusdtdata = data.map(d => {
        return {
            Open: parseFloat(d[1]),
            High: parseFloat(d[2]),
            Low: parseFloat(d[3]),
            Close: parseFloat(d[4]),
            Volume: parseFloat(d[5]),
            Timespan: 30,
        }
    });
    console.log(btcusdtdata);
    saveToDatebase(symbol, btcusdtdata);
    //recursive functions are complicated, we can get rid of it here
    //by moving the responsibility to the caller
};

也许有办法将数据从MongoDB返回到Node.JS并在那里进行计算,然后将其存储回另一个MongoDB集合中?

完整代码,以更好地了解脚本的工作方式

const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
const fetch = require("node-fetch");

const symbols = ["ADABTC",
    "AEBTC",
    "AIONBTC",
    "ALGOBTC",
    "ARDRBTC",
    "ARKBTC"
];

const getBTCData = async symbol => { //make this function accept the current symbol
    //async/await lets us write this much nicer and with less nested indents
    let data = await fetch(`https://api.binance.com/api/v3/klines? 
symbol=${symbol}&interval=30m&limit=1`).then(res => res.json());
    const btcusdtdata = data.map(d => {
        return {
            Open: parseFloat(d[1]),
            High: parseFloat(d[2]),
            Low: parseFloat(d[3]),
            Close: parseFloat(d[4]),
            Volume: parseFloat(d[5]),
            Timespan: 30,
        }
    });
    console.log(btcusdtdata);
    saveToDatebase(symbol, btcusdtdata);
    //recursive functions are complicated, we can get rid of it here
    //by moving the responsibility to the caller
};

//helper function for an awaitable timeout
const sleep = ms => new Promise(res => setTimeout(res, ms));

const j = schedule.scheduleJob('*/30 * * * *', async() => {
    //expand this function to be responsible for looping the data
    for (let symbol of symbols) {
        //we can pass symbol to getBTCData instead of making it
        //responsible for figuring out which symbol it should get
        await getBTCData(symbol);
        await sleep(3000);
    }
});

//make this a helper function so `saveToDatabase()` isn't also responsible for it
const getDateTime = () => {
    let today = new Date();
    let date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
    let time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
    return date + ' ' + time;
};

const saveToDatebase = async(symbol, BTCdata) => {
    const url = 'mongodb+srv://USERNAME:PASSWORD@cluster0-1kunr.mongodb.net/<dbname>?retryWrites=true&w=majority';

    let dateTime = getDateTime();

    //use await here and below to vastly simplify this function
    let db = await MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true });
    const dbo = db.db('CryptoCurrencies');
    const myobj = { Name: symbol, Array: BTCdata, Date: dateTime };
    await dbo.collection(symbol).insertOne(myobj);
    console.log('1 document inserted');
    db.close();
};

关于我该如何做的任何解决方案或可以帮助我解决此问题的文档。

赞赏有关此任务的任何想法/帮助。

0 个答案:

没有答案