Get perticular records based on the hour and the driverID - mongodb

I'm creating a mongo database which stores array of objects of the following form
{
_id: 5ca37dc35b55092ab2b0980e,
driverID: 'cjttwclbr00ui0714y2dodxe2',
createdAt: 2019-04-02T15:20:35.021Z,
updatedAt: 2019-04-02T15:20:35.021Z, __v: 0
}
I want to filter those results which belongs to a particular driver based on the day and hour
eg: I want to get all the records which created on 2nd hour of today which belongs to a particular driver
How can I write find query or aggregation method based on this scenario?
I can get hour of the day using
const hour = new Date().getHours();

To get all the driver data b/w a particular hour
var date = new Date(); // for today
date.setHours(n,0,0,0); // n is the hour
var endHour = new Date();
endHour.setHours(n+1,0,0,0);
var query = {
driverID:driverId,
createdAt :{ $gte:date,$lt:endHour}
}
db.collection.find(query);

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.

Mongodb get data using ISO format date

I am saving data into mongodb and the dates are in this format for instance
7/30/1960 (july 30, 1960) is ISODate("1960-07-30T05:00:00.000+0000"),
I want to find records created today(and i dont care about the time,so long as its today) and i have this
var start = new Date();
var end = new Date();
and to display the data
db.posts.find({created_on: {$gte: start, $lt: end}});
Will this work or must i convert my iso dates to another format first?.
You can alter the 'start' and 'end' variables before querying:
var start = new Date();
start.setHours(0,0,0,0); // remove time part from the date
var end = new Date();
end.setHours(0,0,0,0); // remove time
end.setDate(end.getDate() + 1); // add a day to the end date
and then you can use your query:
db.posts.find({created_on: {$gte: start, $lt: end}});

get records created within 24 hour in sails js

I want to fetch the Posts which are created within 24 hours in sails js. And I am using mongodb database. How do I get all those Posts which are created in past 24 hours.
You can create a date range that consists of 24 hours in the following manner.
Using the momentjs library, you can create a date with the extension methods subtract() and cast it to a JS Date with the toDate() method:
var start = moment().subtract(24, 'hours').toDate();
or with plain vanilla Date objects, create the date range as:
var now = new Date(),
start = new Date(now.getTime() - (24 * 60 * 60 * 1000));
Use the where() method to use the query the Posts model using the above date range query, given the field which holds the timestamp is called date:
Posts.find()
.where({ "date" : { ">": start } })
.exec(function (err, posts) {
if (err) throw err;
return res.json(posts);
});

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))}},