How to get the total number of records for the current day? I get 0 as a result, although I have a couple of entries.
module.exports.getOnline = async function (req, res) {
try {
var current_date = new Date().toISOString()
const online = await Online.find({ Date: current_date })
res.status(200).json(online.length)
} catch (e) {
errorHandler(res, e)
}
}
I think that currently you are searching for records with a specific date and time. Try to look for a range of dates, with today at 00:00 and today at 23:59.
This one might help:
https://stackoverflow.com/a/2943685/12647796
edit - I tried to match it to your problem
var min_date = new Date();
var max_date = new Date();
min_date.setHours(0,0,0,0);
max_date.setHours(23,59,59,999);
const online = await Online.find({
Date: {
$gte: min_date,
$lt: max_date
}
})
res.status(200).json(online.length)
var current_date = new Date().toISOString()
The toISOString() method converts a Date object into a string, using the ISO standard.
The standard is called ISO-8601 and the format is: YYYY-MM-DDTHH:mm:ss.sssZ
so when you get the current date and using this method it will not match with the existing records in database.that's why query return 0.
if you want to get the current day records you need to use following code for getting current date,month and year than use it for query.
module.exports.getOnline = async function (req, res) {
try {
var d = new Date();
var date = d.getDate();
var month = d.getMonth() + 1; // Since getMonth() returns month from 0-11 not 1-12
var year = d.getFullYear();
var dateStr = date + "/" + month + "/" + year;
const online = await Online.find({ Date: dateStr })
res.status(200).json(online.length)
} catch (e) {
errorHandler(res, e)
}
}
I think this will help you.
Related
Hello im trying to query my mongoDB collection to find all data from specific date.
For some reason when I use Find() with the object specified as param in the call it works
but when I try to declare a variable it doesnt .... can some explain me why?
this doesnt work
//Convert Date to short Date string
let day = foundRapport.date.getUTCDate();
let fullMonth = foundRapport.date.getMonth() + 1;
let year = foundRapport.date.getFullYear();
let date = `${day}/${fullMonth}/${year}`;
//query for Date_Travail
let query = {};
let criteria = "Date_Travail";
query[criteria] = date;
console.log(query); // this returns { Date_Travail: '24/7/2020' }
//Find data with query as param
Heures.find(query, (err, foundHours) => {
if (err) {
console.log(err);
} else {
res.render("rapportDetail", {
rapport: foundRapport,
shortDate: date,
hours: foundHours,
});
}
});
But this here does....
//Convert Date to short Date string
let day = foundRapport.date.getUTCDate();
let fullMonth = foundRapport.date.getMonth() + 1;
let year = foundRapport.date.getFullYear();
let date = `${day}/${fullMonth}/${year}`;
// let query = {};
// let criteria = "Date_Travail";
// query[criteria] = date;
// console.log(query);
//Find data with object as param
Heures.find({Date_Travail: "24/07/2020"}, (err, foundHours) => {
if (err) {
console.log(err);
} else {
res.render("rapportDetail", {
rapport: foundRapport,
shortDate: date,
hours: foundHours,
});
}
});
can anyone point me on the direction of why?
Thanks
I want to create a script which is taking the average of the Volume for last 7(for example) days.
I'm stuck with aggregation stages since first stage I need to take Date for last 7 days and in second stage calculate Average of Volume
Package list:
Node-schedule - */1 * * * * (Runs the script every minute)
Binance API - Taking data from them.
Screenshot for showcasing how the document looks like in MongoDB.
Aggregation part of the Code.
const average = await dbo.collection(symbol).aggregate([{
'$match': {
'Date': { '$gte': new Date((new Date().getTime() - (7 * 24 * 60 * 60 * 1000))) }
},
},
{
'$group': {
_id: null,
'Volume': { '$avg': '$Volume' }
},
}
]).toArray();
This code returns me an empty array in terminal like this > []
Full Code here.
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);
//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('*/1 * * * *', 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(8000);
}
});
//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) => {
try {
const url = 'mongodb://username:password#ipadress:port/dbname';
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': {
'Date': { '$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)
}
};
EDIT1
If I delete $match part my script is working and I receive average of Volume.
Screenshot of terminal after success try without $match
EDIT2
According to the last answer I understand that I need to change Date format from string to object, but I really can't get how I can do it in this part?
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;
};
EDIT3
After editing the Date format I receive a Document in MongoDB in strange Date format like - Date:2020-07-20T13:24:02.390+00:00
Code here:
const getDateTime = () => {
let today = new Date();
let date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
let time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
return new Date();
};
The problem is on the Date field format.
The getDateTime function returns a string so Mongo is managing the field as a string not as a Date object so the $gte check will compare string not dates.
You should change the function to getDateTime = () => new Date(). Mongo will manage the date correctly storing in UTF Timezone.
Tring to query a date-string in the $match field would be really difficult.
Edit:
To update the typing just:
const getDateTime = () => {
return new Date();
};
Good afternoon, I have a script which is receiving data from Binance API every 30 minutes and saves it in MongoDB specific database in different collections.
My MongoDB is installed on VPS. I'm connecting to it from my local computer.
Problem is that I leave my code to work constantly for ± 3 days and I receive that sometimes data did not save on specific collection or missed, etc. How I can configure my code or what can I do to create a perfect connection to save all data correctly.
Problem Explanation:
I have an array with
symbols=["ada","ae","kava","eth","etc","zrx","xzc","faq","gas","vfg","req"];
And when I leave the code for let's say 25 hours. I suppose to see 50 documents on every collection name.
But I receive that some collections got 48 documents saved instead of 50, some of them got 49, some of them got 50 like sometimes collections didn't save d properly.
FULLCODE HERE:
const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
const fetch = require("node-fetch");
const symbols=["ada","ae","kava","eth","etc","zrx","xzc","faq","gas","vfg","req"];
//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);
//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(8000);
}
});
//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://username:password#server:port/dbname?retryWrites=true&w=majority';
let dateTime = getDateTime();
//use await here and below to vastly simplify this function
let db = await MongoClient.connect(url, { useUnifiedTopology: true });
const dbo = db.db('Crypto');
const myobj = { Name: symbol, Array: BTCdata, Date: dateTime };
await dbo.collection(symbol).insertOne(myobj);
console.log('1 document inserted');
db.close();
};
Goal: Solve the saving issue, I think it also can be possible something with VPS response itself. How can I maybe update my code that it looks cleaner and faster if possible?
Any suggestions or help really appreciated.
can anyone help me how can i save documents in mongodb using nodejs driver with
a field createdDate in the date format dd.mm.yyyy
I have tried to do so but in schema on type:date is getting accepted
and when type:string i am still unable to save the date
let today = new Date();
let day = today.getDate();
let month = today.getMonth() + 1;
let year = today.getFullYear();
let hour = today.getHours();
let minutes = today.getMinutes();
let seconds = today.getSeconds();
crdate =`${day}.${month}.${year}.${hour}.${minutes}.${seconds}`
const order = new VendorOrder({
...req.body,
vendorOrders: req._id,
crdate
});
try {
await order.save();
res.status(201).send(order);
} catch (e) {
res.status(400).json({
message: "unable to create order"
});
}
};
I'm using Express & Node.js.
router.get('/:year?/:month?/:day?', function(req, res) {
var date = moment();
if (req.params.year && req.params.month && req.params.day) {
var dateString = req.params.year + " " + req.params.month + " " + req.params.day;
var tempDate = moment(dateString, "DD MM YYYY");
if (tempDate.isValid()) {
date = tempDate;
}
}
.catch(function (err) {
console.error(err);
res.send("Error");
});
});
The above isn't my full code for my route. But I need some pointers. I'm using Moment.js(http://momentjs.com/) to grab the current date, format it and pass it through the url in the route.get request.
However, I don't want the user to be able to go to a past date. So if the date has already been and the user tries to navigate too it I want to redirect them back to the current date.
.then (function(){
var pastDate = function(req, res) {
if (req.query.[pastDate]) {
res.redirect('/');
} else {}
}
})
I don't think the the syntax is correct. But not sure if i'm looking on the right lines in how I'd do this.
Thanks for help.
I looked through your code and it looks really inconsisten and I don't fully understand what you're trying to do, but you can probably narrow it down to something like this:
router.get('/:year?/:month?/:day?', function (req, res) {
var year = req.params.year;
var month = req.params.month;
var day = req.params.day;
if (year && month && day) {
var requestDate = moment(day + ' ' + month + ' ' + year);
var today = moment();
if (requestDate.isValid() && !requestDate.isBefore(today)) {
// All set and valid, do stuff with the request
} else {
// Invalid date or the requested date is before today
// Redirecting to /year/month/day of this day, e.g /2015/04/31
return res.redirect('/' + today.year() + '/' + today.month() + '/' + today.date());
}
}
});
Moment has an isBefore method that is really handy for these kind of tasks.
You should use a bit more variables in your code so it's easier to work with! :)
You should be able to just do a less than comparison.
var goodDate = function() {
var now = moment();
if (this < now) {
return false
}
return true
}