Javascript 计算MongoDB聚合和NodeJS中最近200天的平均值
我有一个脚本,用于计算MongoDB中每个集合的平均Javascript 计算MongoDB聚合和NodeJS中最近200天的平均值,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,我有一个脚本,用于计算MongoDB中每个集合的平均Volume数据。但由于我有超过1000天的记录,我只想计算过去200天的平均量 目前,我的脚本正在收集所有数据(1000天以上) 目标:如何设置最近200天的范围,以计算他们的平均量。还有一件非常重要的事情,就是每天我仍然只想使用最后200天 平均聚合框架 const saveToDatebase = async(symbol, BTCdata) => { try { const url = 'mongodb:/
Volume
数据。但由于我有超过1000天的记录,我只想计算过去200天的平均量
目前,我的脚本正在收集所有数据(1000天以上)
目标:如何设置最近200天的范围,以计算他们的平均量。还有一件非常重要的事情,就是每天我仍然只想使用最后200天
平均聚合框架
const saveToDatebase = async(symbol, BTCdata) => {
try {
const url = 'mongodb://username:passwprd@ipaddress/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 = await dbo.collection(symbol).aggregate([{
'$group': {
_id:null,
'Volume': {
'$avg': '$Volume'
}
}
}]).toArray();
console.log('1 document inserted');
console.log(average);
db.close();
} catch (e) {
console.error(e)
}
};
EDIT1
像这样编辑代码之后>>
const average = await dbo.collection(symbol).aggregate([{
$match: {
$gte: ["$dateTime", { $subtract: ["$$NOW", 200 * 60 * 60 * 24 * 1000] }]
},
"$group": {
_id: null,
"Volume": {
"$avg": "$Volume"
}
}
}]).toArray();
我收到此错误>MongoError:管道阶段规范对象必须仅包含一个字段。
EDIT2
代码使用下面的代码后,我收到此错误-MongoError:未知的顶级操作员:$gte
const average = await dbo.collection(symbol).aggregate([{
$match: { $gte: ["$dateTime", { $subtract: ["$$NOW", 200 * 60 * 60 * 24 * 1000] }] }
},
{
"$group": {
_id: null,
"Volume": {
"$avg": "$Volume"
}
}
}
])
以下是文档在MongoDB中的外观
EDIT3
下面是关于上次改进的代码。代码正常运行是唯一的问题,它没有返回平均值。在我的终端中,我收到一个空数组[]
,但我没有收到任何错误。我认为问题就在这里-“$dateTime”
我认为对它的查询是错误的。因为我也在尝试在MongoDB Compass中实现它。也不管用
此处编码
const average = await dbo.collection(symbol).aggregate([{
$match: {
$expr: {
$gte: [
"$dateTime",
{
$subtract: [
"$$NOW",
200 * 60 * 60 * 24 * 1000
]
}
]
}
}
},
{
"$group": {
_id: null,
"Volume": {
"$avg": "$Volume"
}
}
}
]).toArray();
EDIT4
现在唯一的问题是我收到了一个空数组>[]
我收到了一个空数组,因为日期
保存为字符串
到MongoDB,但为了使聚合框架工作,我需要将其存储为对象
在下面的代码中,有我创建日期函数的方法,它在MongoDB中将其保存为string
如何将其更改为object
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) => {
try {
const url = 'mongodb://username:password@ipadress/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 = await dbo.collection(symbol).aggregate([{
'$match': {
'dateTime': { '$gte': new Date((new Date().getTime() - (7 * 24 * 60 * 60 * 1000))) }
},
},
{
'$group': {
_id: null,
'Volume': { '$avg': '$Volume' }
},
}
]).toArray();
console.log('1 document inserted');
console.log(average);
db.close();
} catch (e) {
console.error(e)
}
};
来自MongoDB的文档作为文本:
{
"_id": {
"$oid": "5f158c9d80d84408f6c38d8b"
},
"Name": "ADABTC",
"Date": "2020-7-20 13:22:53",
"Open": 0.0000133,
"High": 0.0000133,
"Low": 0.00001325,
"Close": 0.00001326,
"Volume": 1189734,
"Timespan": 30
}
在对文档进行分组之前,必须对其进行筛选。应该是这样的:
db.collection.aggregate([
{
$addFields: {
DateObj: {
$regexFindAll: { input: "$Date", regex: "\\d+" }
}
}
},
{
$set: {
DateObj: {
$dateFromParts: {
year: { $toInt: { $arrayElemAt: ["$DateObj.match", 0] } },
month: { $toInt: { $arrayElemAt: ["$DateObj.match", 1] } },
day: { $toInt: { $arrayElemAt: ["$DateObj.match", 2] } },
hour: { $toInt: { $arrayElemAt: ["$DateObj.match", 3] } },
minute: { $toInt: { $arrayElemAt: ["$DateObj.match", 4] } },
second: { $toInt: { $arrayElemAt: ["$DateObj.match", 5] } },
timezone: "Europe/Zurich"
}
}
}
},
{
$match: {
$expr: {
$gte: ["$DateObj", { $subtract: ["$$NOW", 200 * 60 * 60 * 24 * 1000] }]
}
}
},
{
"$group": {
_id: null,
"Volume": {
"$avg": "$Volume"
}
}
}
])
@WenfriedDomscheit我认为有一些打字错误导致一个括号显示错误。还是谢谢你的回答!编辑代码后立即进行测试您的方式收到此错误-MongoError:unknown top level operator:$gte@WenfriedDomscheit你好!我测试了你的答案,它工作正常,但没有显示平均值-在终端中,我收到任何空数组>[]没有错误消息。要根据更新我的问题,请以格式化文本而不是图像的形式提供示例文档可能问题在于我将日期保存为字符串,但它应该是一个对象。目前,我一直在研究如何将MongoDB中的日期保存为对象,而不像Strings。你的Date
属性是字符串(=非常糟糕)还是Date
对象(应该是这样)?@WernfriedDomscheit是的,它是字符串。const myobj=object.assign({Name:symbol,Date:dateTime},BTCdata[0]);这就是它的样子,有没有关于如何将它改为object而不是string的想法?