Two date find between two data in collection - mongodb

I have below collection data in mongo db.
"enddate" : ISODate("2019-03-27T14:30:00.000Z"),
"date" : ISODate("2019-03-27T10:30:00.000Z"),
I have two date like start date "2019-03-26T19:30:00.000Z" and end date "2019-03-26T20:30:00.000Z"
I want to find above two date time period exits in collection or not.
Please help to make mongodb query.

advt.date = m.utc().toISOString();
advt.enddate = me.utc().toISOString();
advt.time = m.utc().toISOString();
advt.endtime = me.utc().toISOString();
var Query = Advertisement.find({
$or: [
{ $and:[{ date: { $gte: advt.date }, enddate:{ $lte: advt.enddate } }] } ,
{ $and:[{ enddate: { $gte: advt.date }, date:{ $lte: advt.enddate } }] }
],"ad_type":"splash", "isDeleted":false, "_id":{ $ne: advt._id }
});

You can use ObjectId.getTimestamp() for that purpose.
Also check this Link

Related

MongoDB: Update 1 field in each document in a collection

I have a mongo collection that consist of many documents but I want to update a single field that is currently a string to a ISODate object.
Collection = {
{ _id: ObjectId('1'), date: '2022-01-01T01:00:00.000Z' },
...
};
What I am looking for
Collection = {
{ _id: ObjectId('1'), date: ISODate('2022-01-01T01:00:00.000Z') },
...
};
I figured I could go do a db.get('Collection').find({}).forEach(... update logic); but I am unsure how I would set that up.
I appreciate any type of help
EDIT: I figured it out after receiving some help
db.getCollection('Collection').find({"date": { "$exists": true, "$type": 2 }}).forEach(function (doc) {
var newDate = new Date(doc.date);
db.getCollection('Collection').findAndModify({query: { "_id": doc._id }, update: {
$set: {
"date" : newDate
}
}})
})
Don't do find().forEach() because it's going to cause you to stream all of the data to the client and then back.
Instead, just issue an update that can be executed on the server by itself. The general approach is documented here. For your specific situation you want something like this:
db.collection.update({},
[
{
$set: {
date: {
$dateFromString: {
dateString: "$date"
}
}
}
}
])
Working playground example here.

MongoDB date math with aggregation variable

I'm trying to build an aggregation of things that haven't reported in by some interval (heartbeat) - I need to calculate a value based on a stored heartbeat:
db.things.aggregate([
{$project: {"lastmsg":1, "props.settings":1}},
{$unwind: "$props.settings"},
{$project: {
_id:0,
"lastmsg": "$lastmsg",
"heartbeat": {$multiply: [{$toInt: "$props.settings.heartbeat"},2000]},
"now": new Date(), "subtracted": new Date(new Date().getTime()- "$heartbeat")
}
}
])
Result returned is like this:
{ "lastmsg" : ISODate("2020-04-23T12:41:37.667Z"), "heartbeat" : 240000, "now" : ISODate("2020-05-14T16:26:11.824Z"), "subtracted" : ISODate("1970-01-01T00:00:00Z") }
{ "lastmsg" : ISODate("2020-05-14T16:24:24.228Z"), "heartbeat" : 240000, "now" : ISODate("2020-05-14T16:26:11.824Z"), "subtracted" : ISODate("1970-01-01T00:00:00Z") }
The "subtracted" projection is not doing the date math as expected. I can plug in a specific number and it works but this defeats the purpose...
As a last step I will match to see what of these things hasn't checked in within the interval of heartbeat:
{ $match: { "lastmsg":{$gte: "$subtracted")}
Any help would be greatly appreciated...
I don't know how your data is like (you should post your data to help), but I think this can solve the problem.
You can use the $$NOW variable, that returns the current date in ISODate format.
Test data:
[
{
"lastmsg": ISODate("2020-04-23T12:41:37.667Z"),
"heartbeat": 240000
},
{
"lastmsg": ISODate("2020-05-14T16:24:24.228Z"),
"heartbeat": 240000
}
]
Query:
db.collection.aggregate([
{
$addFields: {
"now": "$$NOW",
"subtracted": {
$subtract: [
"$$NOW",
"$heartbeat"
]
}
}
},
{
$match: {
"lastmg": {
$gte: "$subtracted"
}
}
}
])

MongoDB Mongoose select documents between a date range

I've a collection called events. Sample document is like this.
I want to select documents with in date range of '2019-01-11' to '2019-11-27'.
What I've done is this. But this seems not working.
How do I achieve this using MongoDB Mongoose?
$match: {
createdAt: {
$gte: {
$dayOfYear: '2019-01-11'
},
$lte: {
$dayOfYear: '2019-11-27'
}
}
}
Use the Date() object instead. I am not sure if this affects the timezone as well.
db.collection.find({
"createdAt": {
"$gte": new Date('2019, 1, 11'),
"$lt" : new Date(2019, 11, 27)
}
})

Date range not working in aggregation pipeline, but works in find()

I am trying to filter data by a date range. Example return the data that was created no more than 14 days ago.
I can do this in find with the following:
{
$match: {
eventTime: { $gte: startTime.toDate(), $lte: endTime.toDate() }
}
}
eventTime is an ISO date as well as startTime and endTime
I am using an aggregation and a lookup and trying to implement the same thing:
{
$lookup:
{
from: "data",
let: { dataId: "$dataId", patientId: "$patientId" },
pipeline: [
{
$match:
{
$expr:
{
$and:
[
{ $eq: ["$patientId", patientId] },
{ $eq: ["$dataId", "$$dataId"] },
{ $gte: ["$eventTime", startTime.toDate()] },
{ $lte: ["$eventTime", endTime.toDate()] },
]
}
}
}
],
as: "data"
}
}
But no data results are returned. If I remove the dates I get all the correct data based on dataId and patient. so the join is working.. but somehow the date range is not.
Again both the eventTime and startTime and endTime are all ISO dates.
example :
let endTime = Moment(new Date());
let startTime = Moment().subtract(days, "days");
"eventTime": "2019-08-07T03:37:40.738Z"
startTime "2019-07-30T00:02:11.611Z"
endTime "2019-08-13T00:02:11.610Z"
End time is 'today'
so in the example here the data time is between the two dates and should be returned.
I looked there : https://docs.mongodb.com/manual/reference/operator/aggregation/gte/
and it should work.. but not the case
I tried:
{eventTime: { '$gte': new Date(startTime), $lte: new Date(endTime)}}
and I get:
MongoError: An object representing an expression must have exactly one field: { $gte: new Date(1564495211043), $lte: new Date(1565704811042) }
also tried:
{ eventTime: {'$gte': new Date(startTime)}}
and get:
MongoError: Expression $gte takes exactly 2 arguments. 1 were passed in.
also tried:
{ $eventTime: {'$gte': new Date(startTime)}}, {$eventTime: {'$lte': new Date(endTime)}}
and get: MongoError: Unrecognized expression '$eventTime'
Any insight would certainly be appreciated
I was able to get it working via toDate:
{
$match:
{
$expr:
{
$and:
[
{ $eq: ["$patientId", patientId] },
{ $eq: ["$dataId", "iraeOverallAlert"] },
{ "$gte": [ {$toDate: "$eventTime"}, startTime.toDate()] },
{ "$lte": [ {$toDate: "$eventTime"}, endTime.toDate()] },
]
}
}
},
Note: This was not needed in the find, but somehow was needed using aggregation. Makes no sense but yah for trial and error.

MongoDB how to fetch documents based on multiple dates

I have a collection of events, each have a start date. I want to fetch data starting on specific dates only. How will i do that ? I found a lot of solutions for date ranges but this case is different. If client inputs two dates i need to fetch only the events starting on those two dates, no need of dates in between. I tried using $or, $in etc but no use. The below code will not work.
let query = {
startDate: {
$or: [
{
$gte: new Date("2018-05-10T00:00:00.000Z"),
$lt: new Date("2018-05-10T23:59:59.000Z")
},
{
$gte: new Date("2018-08-06T00:00:00.000Z"),
$lt: new Date("2018-08-06T23:59:59.000Z")
}
]
}
};
Found the answer.
let query = {
$or: [
{
startDate: {
$gte: new Date("2018-05-10T00:00:00.000Z"),
$lt: new Date("2018-05-10T23:59:59.000Z")
}
},
{
startDate: {
$gte: new Date("2018-08-06T00:00:00.000Z"),
$lt: new Date("2018-08-06T23:59:59.000Z")
}
}
]
};