Date Range Mongo Query using Meteor Js - mongodb

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.

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.

Finding Documents created today

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()

mongodb- How to display a year from a date in find method

Im trying to display the years of date properties in a mongodb collection.
I have collection of vehicles that contains objects with a date property:
manufacturingDate - Date (ISODate).
To display only the years there is one way to this with aggregate:
db.vehicles.aggregate(
[
{ $project: { year: { $year: "$manufacturingDate" } } }
]
)
But I am not allowed to use aggregate so i need a way to take the year out of the ISODate in another way.
I have tried many things like:
db.vehicles.find({}, { manufacturingDate: { $year: 1 } } )
or:
db.vehicles.find({}, { year: { function() { return this.manufacturingDate.getFullYear() } } } )
But these are all syntax errors.
So i hope you have a correct way to do this without aggregate. I prefer the find method but any other method will be good.
Thanks.
Here are two ways to do it. Of course; it would be nicer if we could just execute getFullYear within a forEach applied to the find() but this is what works for me so far.
I found this on [link]http://grokbase.com/t/gg/mongodb-user/133nvkd48q/how-to-format-output-datetime and tweaked the example. Obviously there is more here than you need bu I left the extra bits for clarity.
//first create a function to handle the execution of the getFullYear function on the ISODate field.
function parse_date(obj) {
year = obj['manufacturingDate'].getFullYear();
month = obj['manufacturingDate'].getMonth() + 1;
day = obj['manufacturingDate'].getUTCDate();
hour = obj['manufacturingDate'].getUTCHours();
minute = obj['manufacturingDate'].getUTCMinutes();
obj['manufacturingDate'] = year + '/' + month + '/' + day + ' ' + hour +
':' + minute
//printjson(obj);
printjson(year);
}
//then execute your query and apply the parse_date function above within
the forEach of the find method.
db.sample.find({},{manufacturingDate:1}).forEach(parse_date)
You can also iterate over the resultset as a cursor and applying the getFullYear function against the ISODate field.
//iterate over cursor
var mdate = myDocument.manufacturingDate;
print (mdate.getFullYear());

uses for mongodb ObjectId creation time

The ObjectId used as the default key in mongodb documents has embedded timestamp (calling objectid.generation_time returns a datetime object). So it is possible to use this generation time instead of keeping a separate creation timestamp? How will you be able to sort by creation time or query for the last N items efficiently using this embedded timestamp?
I suppose since MongoDB ObjectId contain a timestamp, you can sort by 'created date' if you will sort by objectId:
items.find.sort( [['_id', -1]] ) // get all items desc by created date.
And if you want last 30 created items you can use following query:
items.find.sort( [['_id', -1]] ).limit(30) // get last 30 createad items
I am actualy not sure,i just suppose that ordering by _id should work as described above. I'll create some tests later.
Update:
Yes it is so. If you order by _id you will automatically order by _id created date.
I've done small test in c#, mb someone interest in it:
public class Item
{
[BsonId]
public ObjectId Id { get; set; }
public DateTime CreatedDate { get; set; }
public int Index { get; set; }
}
[TestMethod]
public void IdSortingTest()
{
var server = MongoServer.Create("mongodb://localhost:27020");
var database = server.GetDatabase("tesdb");
var collection = database.GetCollection("idSortTest");
collection.RemoveAll();
for (int i = 0; i <= 500; i++)
{
collection.Insert(new Item() {
Id = ObjectId.GenerateNewId(),
CreatedDate = DateTime.Now,
Index = i });
}
var cursor = collection.FindAllAs<Item>();
cursor.SetSortOrder(SortBy.Descending("_id"));
var itemsOrderedById = cursor.ToList();
var cursor2 = collection.FindAllAs<Item>();
cursor2.SetSortOrder(SortBy.Descending("CreatedDate"));
var itemsOrderedCreatedDate = cursor.ToList();
for (int i = 0; i <= 500; i++)
{
Assert.AreEqual(itemsOrderedById[i].Index, itemsOrderedCreatedDate[i].Index);
}
}
Yes, you can use the generation_time of BSON ObjectId for the purposes you want. So,
db.collection.find().sort({ _id : -1 }).limit(10)
will return the last 10 created items. However, since the embedded timestamps have a one second precision, multiple items within any second are stored in the order of their creation.
The code to convert a DateTime to its corresponding timestamp with the c# driver is as follows:
public static ObjectId ToObjectId(this DateTime dateTime)
{
var timestamp = (int)(dateTime - BsonConstants.UnixEpoch).TotalSeconds;
return new ObjectId(timestamp, 0, 0, 0);
}
More info here: http://www.danharman.net/2011/10/26/mongodb-ninjitsu-using-objectid-as-a-timestamp/
From: http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps
"sorting on an _id field that stores ObjectId values is roughly equivalent to sorting by creation time, although this relationship is not strict with ObjectId values generated on multiple systems within a single second."
See
http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-DocumentTimestamps
Likely doable however I would always prefer having a dedicated timestamp instead of relying on some such internals like timestamp somehow embedded in some object id.
To query projects created within 7 days, I use below snippet:
db.getCollection('projects').find({
$where: function() {
// last 7 days
return Date.now() - this._id.getTimestamp() < (7 * 24 * 60 * 60 * 1000)
}
}).sort({
'_id': -1
})
and if you want to get items with specified fields:
db.getCollection('projects').find({
$where: function() {
// last 7 days
return Date.now() - this._id.getTimestamp() < (7 * 24 * 60 * 60 * 1000)
}
}).sort({
'_id': -1
}).toArray().map(function(item) {
var res = {};
res['Project Name'] = item.config.label;
res['Author'] = item.author;
res['Created At'] = item._id.getTimestamp().toLocaleDateString();
res['Last Modified Date'] = item.config.lastModifDate.toLocaleString();
return res;
});
it will return something like this:
[{
"Project Name": "Newsletter",
"Author": "larry.chen",
"Created At": "Thursday, January 19, 2017",
"Last Modified Date": "Thursday, January 19, 2017 17:05:40"
}...]
PS: the software I use to connect to MongoDB is Robo 3T
Hope this will help you.
For those wanting to truly use ObjectId for datetime, and not just rely on the fact that ObjectId's are always increasing over time and can therefore be used to order documents by creation time indirection, then here's how:
One can create their filter criteria to return documents whose IDs were made in some datetime range (in Python) by making a dummy ObjectID.from_datetime() like so:
# gets docs which were created in last 5 minutes
resp = await collection.update_one({'_id': {'$gte': ObjectId.from_datetime(datetime.utcnow() - timedelta(minutes=5))}},