Finding Documents created today - mongodb

So, In meteor, I am trying to count the number of documents created today. Obviouly the code below tries to match it to the time of the day along with the date.
var ct2 = Bids.find({$and:[{bidder:currentUser},{createdAt:Date()}]}).count();
How do I go about finding the number of documents for today ?
Thanks in advance.

You might need to do something like this
Query to get last X minutes data with Mongodb
var ct2 = Bids.find({
$and: [
{ bidder: currentUser },
{
createdAt: { $gt: new Date(Date.now() - (1000 * 60 * 60 * 24)) }
}
]
}).count();

By using moment js:
date=moment().add(-1,'days').toISOString();
val1 = checkdate1.substring(0, 11)
temp=val1+'23:59:59.'
val3=date.substring(20,25)
val4=temp+val3;
count = Bids.find({"createdAt": {$gt:new Date(val4)}}).count()

Related

How to compare two dates with Mongodb (find query using NestJS)

I'm trying to get the list of posts for which the publish date is equal or less than the current date.
I'm using NestJS, Mongo & typeORM; which syntax should I use?
const posts =
await this.mbRepository.find(
{ where: { "deletedAt": null , "publishDate" <= currentDate } }
);
let firstPoint = new Date();
firstPoint.setHours(0);
firstPoint.setMinutes(0);
firstPoint.setSeconds(0);
let lastPoint = new Date();
lastPoint.setHours(23);
lastPoint.setMinutes(59);
lastPoint.setSeconds(59);
const posts = await this.mbRepository.find({ publishDate: { $gte: firstPoint, $lt: lastPoint } } });
Get current day and make two point. One as begining of the day and another as end of the day. Then you can use mongodb operator $gte and $lt. In this way you will get all post which have been publish in this time range.

meteorhacks:aggregate to group mongo documents

This Meteor server code tries to count all the records which are 4 months and newer with property size:'4', color:'white' but account all entires from any one user as one count, so no mater how many documents have been entered by the same user, the are all counted as one. but I am getting nothing in return. any ideas? thx
let date = new Date();
date.setMonth(date.getMonth() - 4);
let doc = UsageCol.aggregate([{
$match: {
createdAt: {
$gte: date,
$lte: new Date()
},
action: 'failBroadcast',
plate: plate
}
}, {
$group: {
_id: {
userId: "$userId"
},
count: {
$sum: 1
}
}
}]);
for (var i = 0; i < doc.length; i++) {
var obj = doc[i];
console.log(JSON.stringify(obj));
}
Alright I just wanted to clear some things up from this morning.
The only reason I recommended moment js was thinking we are storing the date in date type and there is no easy way to dynamically create date in UTC using java script date function
So now that we know you used Date.now() to save the dates, you don't need any moment js.
The correct syntax is
let dateToMillis = Date.now(); //The current millis from epoch.
let dateFrom = new Date(dateToMillis); // Use the current millis from epoch.
let dateFromMillis = dateFrom.setMonth(dateFrom.getMonth() - 4); // The millis 4 months ago from epoch.
Pass dateToMillis and dateFromMillis to aggregation query.

Unordered bulk update records in MongoDB shell

I've got a collection consisting of millions of documents that resemble the following:
{
_id: ObjectId('...'),
value: "0.53"
combo: [
{
h: 0,
v: "0.42"
},
{
h: 1,
v: "1.32"
}
]
}
The problem is that the values are stored as strings and I need to convert them to float/double.
I'm trying this and it's working but this'll take days to complete, given the volume of data:
db.collection.find({}).forEach(function(obj) {
if (typeof(obj.value) === "string") {
obj.value = parseFloat(obj.value);
db.collection.save(obj);
}
obj.combo.forEach(function(hv){
if (typeof(hv.value) === "string") {
hv.value = parseFloat(hv.value);
db.collection.save(obj);
}
});
});
I came across bulk update reading the Mongo docs and I'm trying this:
var bulk = db.collection.initializeUnorderedBulkOp();
bulk.find({}).update(
{
$set: {
"value": parseFloat("value"),
}
});
bulk.execute();
This runs... but I get a NAN as a value, which is because it thinks I'm trying to convert "value" to a float. I've tried different variations like this.value and "$value" but to no avail. Plus this approach only attempts to correct the value in the other object, not the ones in the array.
I'd appreciate any help. Thanks in advance!
Figured it out the following way:
1) To convert at the document level, I came across this post and the reply by Markus paved the way to my solution:
var bulk = db.collection.initializeUnorderedBulkOp()
var myDocs = db.collection.find()
var ops = 0
myDocs.forEach(
function(myDoc) {
bulk.find({ _id: myDoc._id }).updateOne(
{
$set : {
"value": parseFloat(myDoc.value),
}
}
);
if ((++ops % 1000) === 0){
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
}
}
)
bulk.execute();
2) The second part involved updating the array object values and I discovered the syntax to do so in the accepted answer on this post. In my case, I knew that there were 24 values in I ran this separately from the first query and the result looked like:
var bulk = db.collection.initializeUnorderedBulkOp()
var myDocs = db.collection.find()
var ops = 0
myDocs.forEach(
function(myDoc) {
bulk.find({ _id: myDoc._id }).update(
{
$set : {
"combo.0.v": parseFloat(myDoc.combo[0].v),
"combo.1.v": parseFloat(myDoc.combo[1].v),
"combo.2.v": parseFloat(myDoc.combo[2].v),
"combo.3.v": parseFloat(myDoc.combo[3].v),
"combo.4.v": parseFloat(myDoc.combo[4].v),
"combo.5.v": parseFloat(myDoc.combo[5].v),
"combo.6.v": parseFloat(myDoc.combo[6].v),
"combo.7.v": parseFloat(myDoc.combo[7].v),
"combo.8.v": parseFloat(myDoc.combo[8].v),
"combo.9.v": parseFloat(myDoc.combo[9].v),
"combo.10.v": parseFloat(myDoc.combo[10].v),
"combo.11.v": parseFloat(myDoc.combo[11].v),
"combo.12.v": parseFloat(myDoc.combo[12].v),
"combo.13.v": parseFloat(myDoc.combo[13].v),
"combo.14.v": parseFloat(myDoc.combo[14].v),
"combo.15.v": parseFloat(myDoc.combo[15].v),
"combo.16.v": parseFloat(myDoc.combo[16].v),
"combo.17.v": parseFloat(myDoc.combo[17].v),
"combo.18.v": parseFloat(myDoc.combo[18].v),
"combo.19.v": parseFloat(myDoc.combo[19].v),
"combo.20.v": parseFloat(myDoc.combo[20].v),
"combo.21.v": parseFloat(myDoc.combo[21].v),
"combo.22.v": parseFloat(myDoc.combo[22].v),
"combo.23.v": parseFloat(myDoc.combo[23].v)
}
}
);
if ((++ops % 1000) === 0){
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
}
}
)
bulk.execute();
Just to give an idea regarding performance, the forEach was going through around 900 documents a minute, which for 15 million records would have taken days, literally! Not only that but this was only converting the types at the document level, not the array level. For that, I would have to loop through each document and loop through each array (15 million x 24 iterations)! With this approach (running both queries side by side), it completed both in under 6 hours.
I hope this helps someone else.

Date Range Mongo Query using Meteor Js

I have an attribute in my collection called dateacquired and the date is formatted like: 2014-03-28 06:08:00.
I am needing to pull back all documents in my collection that are less than or equal to a month ago from the current date. I am just not sure how to write this query.
Anyone know how to start one something like this?
I assume those dates are stored as strings? You can compare strings with the mongoDB comparison operators $gt or $lt and they work as you’d expect. I’m going to also use Sugar to make my life easier (highly recommended; add via mrt add sugarjs) which gives me the Date.create and Date.format methods which reduce this into a one-liner:
var cursorOfDocumentsSinceOneMonthAgo = yourCollection.find({
dateacquired:
{ $gt: Date.create("1 month ago").format("{yyyy}-{MM}-{dd} {hh}:{mm}:{ss}")
}
});
My meteor method for how many people have signed up in the last nDays:
userCountPreviousDays: function (nDays) {
check(nDays, Number);
var arr = [];
var now = new Date().getTime();
var msInDay = 1000 * 60 * 60 * 24;
for (var i = 0; i < nDays; i++) {
arr[i] = Meteor.users.find({
createdAt: {
$lt: new Date(now - (msInDay * i)),
$gt: new Date(now - (msInDay * (i+1)))
}
}).count();
};
return arr;
}
arr[i] is how many people signed up i days ago.

Doing range queries in Mongoose for Hour / Day / Month/ Year

Trying to figure out how to do this. Basically I want to sort by Hour / Day / Month / Year of my submissions.
Each submission has a created field which contains a Mongoose Date object in the form of "created" : ISODate("2013-03-11T01:49:09.421Z"). Do I need to compare against this in the find() conditions?
Here is my current query (I'm wrapping it in a count for pagination purposes FWIW so just ignore that part):
getSubmissionCount({}, function(count) {
// Sort by the range
switch (range) {
case 'today':
range = now.getTime();
case 'week':
range = now.getTime() - 7;
case 'month':
range = now.getTime() - 31; // TODO: make this find the current month and # of days in it
case 'year':
range = now.getTime() - 365;
case 'default':
range = now.getTime();
}
Submission.find({
}).skip(skip)
.sort('score', 'descending')
.sort('created', 'descending')
.limit(limit)
.execFind(function(err, submissions) {
if (err) {
callback(err);
}
if (submissions) {
callback(null, submissions, count);
}
});
});
Can someone help me figure this out? With that current code it just gives me all submissions regardless of a time range, so I'm obviously not doing something properly
I think, you are looking $lt(Less than) and $gt(Greater Than) operators in MongoDB.
By using above operators the result can be queried according to time.
I am adding possible solution below.
var d = new Date(),
hour = d.getHours(),
min = d.getMinutes(),
month = d.getMonth(),
year = d.getFullYear(),
sec = d.getSeconds(),
day = d.getDate();
Submission.find({
/* First Case: Hour */
created: { $lt: new Date(), $gt: new Date(year+','+month+','+day+','+hour+','+min+','+sec) } // Get results from start of current hour to current time.
/* Second Case: Day */
created: { $lt: new Date(), $gt: new Date(year+','+month+','+day) } // Get results from start of current day to current time.
/* Third Case: Month */
created: { $lt: new Date(), $gt: new Date(year+','+month) } // Get results from start of current month to current time.
/* Fourth Case: Year */
created: { $lt: new Date(), $gt: new Date(year) } // Get results from start of current year to current time.
})