Node.js 如何在MongoDB和NodeJS中聚合平均值

Node.js 如何在MongoDB和NodeJS中聚合平均值,node.js,mongodb,aggregation-framework,Node.js,Mongodb,Aggregation Framework,我试图创建聚合来计算MongoDB中每个集合的平均值 我从Binance API获取数据并将其存储在MongoDB中 我怎样才能纠正这个错误 目标:计算每个不同集合的平均值。 这里是代码的聚合部分 const symbols = ["ADABTC", "AEBTC", "AIONBTC", "ALGOBTC", "ARDRBTC"]; const saveToDatebase = async(s

我试图创建聚合来计算MongoDB中每个集合的平均值

我从Binance API获取数据并将其存储在MongoDB中

我怎样才能纠正这个错误

目标:计算每个不同集合的平均值。 这里是代码的聚合部分

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

const saveToDatebase = async(symbol, BTCdata) => {

const url = 'mongodb://username:password@ip.adress.com/port?<dbname>retryWrites=true&w=majority';
let dateTime = getDateTime();

let db = await MongoClient.connect(url, { useUnifiedTopology: true });
const dbo = db.db('Crypto');
const myobj = Object.assign({ Name: symbol, Date: dateTime }, BTCdata[0]);
await dbo.collection(symbol).insertOne(myobj);
const average = dbo.collection(symbol).aggregate({
    '$group': {
        _id: null,
        'Volume': {
            '$avg': '$Volume'
        }
    }
});
console.log('1 document inserted');
console.log(average);
db.close();
};
    const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
const fetch = require("node-fetch");
const symbols = ["ADABTC", "AEBTC", "AIONBTC", "ALGOBTC", "ARDRBTC"];

//a descriptive name helps your future self and others understand code easier
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);
};

const sleep = ms => new Promise(res => setTimeout(res, ms));

const j = schedule.scheduleJob('* * * * * *', async() => {
    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(8000);
    }
});

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://username:password@server.ip/port?retryWrites=true&w=majority';
    let dateTime = getDateTime();

    let db = await MongoClient.connect(url, { useUnifiedTopology: true });
    const dbo = db.db('Crypto');
    const myobj = Object.assign({ Name: symbol, Date: dateTime }, BTCdata[0]);
    await dbo.collection(symbol).insertOne(myobj);
    const average = dbo.collection(symbol).aggregate({
        '$group': {
            _id: null,
            'Volume': {
                '$avg': '$Volume'
            }
        }
    });
    console.log('1 document inserted');
    console.log(average);
    db.close();
};
EDIT1

添加
await
const average=await dbo.collection(symbol).aggregate([{


不会解决问题。

它与我的关系如何,让我们修复小错误,直截了当地说

saveToDatabase
应该是
saveToDatabase
我想,这是一个语法错误,但重构的决定权在您

第二个是,您应该在
async
函数中使用
try/catch
块,如下所示:

const saveToDatebase = async(symbol, BTCdata) => {
    try { 
      const url = 'mongodb://username:password@server.ip/port?retryWrites=true&w=majority';
      let dateTime = getDateTime();
      let db = await MongoClient.connect(url, { useUnifiedTopology: true });
      const dbo = db.db('Crypto');
      const myobj = Object.assign({ Name: symbol, Date: dateTime }, BTCdata[0]);
      await dbo.collection(symbol).insertOne(myobj);
      const average = dbo.collection(symbol).aggregate([{
        '$group': {
            _id: null,
            'Volume': {
                '$avg': '$Volume'
            }
        }
      }]);
      console.log('1 document inserted');
      console.log(average);
      db.close();
    } catch (e) {
       console.error(e)
    }
};
因为您正在使用node.js(根据问题的标签),而不是Deno

如果您的问题与
$group
阶段有关,则可能在以下位置:

   '$group': {
     _id: null,
     'Volume': {
        '$avg': '$Volume'
      }
此外,请尝试在
$group
阶段使用此代码:

   "$group": {
     _id: "$_id",
     test: {
        "$avg": "$Volume"
      }
您正在尝试
$group
,但我不确定MongoDriver的聚合框架(它的默认版本,不是
mongoose
)确实从集合中获取所有文档,现在尝试删除
$group
阶段,并添加
$match
,然后看一看,仅您的
$match
阶段会获取集合中的所有DB文档,如果是,则添加
$group
阶段

第二件事可能是: 我不太清楚,但请看一看

尝试在聚合框架之前添加
wait
word:
const average=wait dbo.collection(symbol).aggregate({


并确保在数据库连接被关闭之前执行聚合函数。
db.close();

它与我的关系如何,让我们修复小错误,直截了当

saveToDatabase
应该是
saveToDatabase
我想,这是一个语法错误,但重构的决定权在您

第二个是,您应该在
async
函数中使用
try/catch
块,如下所示:

const saveToDatebase = async(symbol, BTCdata) => {
    try { 
      const url = 'mongodb://username:password@server.ip/port?retryWrites=true&w=majority';
      let dateTime = getDateTime();
      let db = await MongoClient.connect(url, { useUnifiedTopology: true });
      const dbo = db.db('Crypto');
      const myobj = Object.assign({ Name: symbol, Date: dateTime }, BTCdata[0]);
      await dbo.collection(symbol).insertOne(myobj);
      const average = dbo.collection(symbol).aggregate([{
        '$group': {
            _id: null,
            'Volume': {
                '$avg': '$Volume'
            }
        }
      }]);
      console.log('1 document inserted');
      console.log(average);
      db.close();
    } catch (e) {
       console.error(e)
    }
};
因为您正在使用node.js(根据问题的标签),而不是Deno

如果您的问题与
$group
阶段有关,则可能在以下位置:

   '$group': {
     _id: null,
     'Volume': {
        '$avg': '$Volume'
      }
此外,请尝试在
$group
阶段使用此代码:

   "$group": {
     _id: "$_id",
     test: {
        "$avg": "$Volume"
      }
您正在尝试
$group
,但我不确定MongoDriver的聚合框架(它的默认版本,不是
mongoose
)确实从集合中获取所有文档,现在尝试删除
$group
阶段,并添加
$match
,然后看一看,仅您的
$match
阶段会获取集合中的所有DB文档,如果是,则添加
$group
阶段

第二件事可能是: 我不太清楚,但请看一看

尝试在聚合框架之前添加
wait
word:
const average=wait dbo.collection(symbol).aggregate({


并确保在数据库连接被关闭之前执行聚合函数。
db.close();

Put
wait
dbo.collection(symbol.aggregate)前面({


const average=await dbo.collection(symbol).aggregate({
Put
await
dbo.collection(symbol.aggregate)前面({


const average=await dbo.collection(symbol).aggregate({

管道阶段不应该出现在聚合方法的数组中吗

aggregate([{
        '$group': {
            _id: null,
            'Volume': {
                '$avg': '$Volume'
            }
        }
    }])

管道阶段不应该出现在聚合方法的数组中吗

aggregate([{
        '$group': {
            _id: null,
            'Volume': {
                '$avg': '$Volume'
            }
        }
    }])

屏幕截图没有显示错误,而是显示错误


要检索结果文档,您需要调用该对象的其中一个方法,例如或。如果未传递回调,大多数方法都会返回一个承诺,因此您需要使用wait。

屏幕截图没有显示错误,而是显示了错误


要检索结果文档,您需要调用该对象的一个方法,例如or。如果没有传递回调,大多数方法都会返回承诺,因此您需要使用wait。

如果排除此函数:
const average=dbo.collection(symbol.aggregate({group stage here});
您是否
saveToDatebase()
效果很好?您是否将每个符号的数据存储在不同的集合中?@AlexZeDim是的,它工作得很好。没有任何问题。在我看来,这个屏幕截图不像是一个错误。它看起来很像一个光标。您是否尝试迭代光标或调用它的
.toArray
方法?@ambianBeing,这就是解决方案。Th非常感谢。您能创建一个我可以投票并确认的答案吗?如果您排除此函数:
const average=dbo.collection(symbol).aggregate({group stage here});
您是否
saveToDatebase()
效果很好?您是否将每个符号的数据存储在不同的集合中?@AlexZeDim是的,它工作得很好。没有任何问题。在我看来,这个屏幕截图不像是一个错误。它看起来很像一个光标。您是否尝试迭代光标或调用它的
.toArray
方法?@ambianBeing,这就是解决方案。Th非常感谢你。你能给我一个我可以投票确认的答案吗?@lfaruki谢谢你的答案!不幸的是,这对我不起作用。有同样的答案problem@lfaruki谢谢你的回答!不幸的是,这对我不起作用。有同样的问题。谢谢你的回答!我刚刚尝试了你的方法,我在我的测试中收到了同样的大错误终端。我在控制台中没有收到平均值的打印。@Hexycode让我们解决它,用集合的模式编辑一个原始问题,在mongoplayground()添加一些示例文档,并通过链接共享,这样我就可以用