I am trying to create a view for records created/modified in last 24 hours.
Is it possible?
Tried creating view as below
db.createView(
"viewname",
"sourcecollection",
[ { $match: {"modifiedTime":{$gte:new Date(Date.now() - 24*60*60*1000), $lte:new Date()}}}]
)
But it translates to static values
{
modifiedTime: {
$gte: ISODate('2022-10-25T23:20:21.602Z'),
$lte: ISODate('2022-10-26T23:20:21.602Z')
}
}
Did read about $$NOW but could not get it working in create view command.
Please suggest
Try this one:
db.createView(
"viewname",
"sourcecollection",
[
{
$match: {
$expr: {
$and: [
{ $gte: ["$modifiedTime", { $dateSubtract: { startDate: "$$NOW", unit: "day", amount: 1 } }] },
{ $lte: ["$modifiedTime", "$$NOW"] }
]
}
}
}
]
)
Based on above post, got it working in Mongo 4.4 with below command.
Dynamic view for records in last 24 hours.
db.createView(
"viewname",
"source",
[ { $match: {$expr: { $gte: [ "modifiedTime" , { $subtract: [ "$$NOW", 24*60*60*1000 ] } ] }}}]
)
Related
Suppose I have this document:
[
{
uuid: 1234,
start: '2022-08-11T16:00:40+08:00',
end: '2022-08-11T16:20:40+08:00'
}
]
How do I get the documents that has a start value in between current date and current date + 30 minutes
This is my current query but it isn't working:
{
start: {
$gte: new Date(),
$lte: {
$dateAdd: {
startDate: new Date(),
unit: 'minute',
amount: 30
}
}
}
}
$dateAdd is an aggregation expression so in order to use it within the query language it must be wrapped with an $expr, like so:
db.collection.find({
$expr: {
$and: [
{
$gte: [
"$start",
"$$NOW"
]
},
{
$lte: [
"$start",
{
$dateAdd: {
startDate: "$$NOW",
unit: "minute",
amount: 30
}
}
]
}
]
}
})
Mongo Playground
Please tell me how can I fulfill the following condition - if the time in the info.startDate field is not equal to 00 hours, increase the date (2021-05-27) by 1 day ahead, set the time to 00:00:00.000Z. I tried to do it clumsily, through Mongock, getting all the elements of the collection and doing a check through LocalDateTime, but my heap overflowed, which is logical because the collection is large. How can I do this through Mongock or at least a manual request to MongoDB. So far I've only written this:
db.getSiblingDB("ervk_core").getCollection("supervision").updateMany(
{},
[
{
"$set": {
"info.startDate": {
"$cond": {
if: {
$eq: [
"$info.startDate",
(there should be a condition at midnight)
]
},
then: (here the day should be added to full and the time should be set to midnight)
}
}
}
}
])
I would like to use dateToString to do a partial search by hour, but as I understand it, this function can only be used in an aggregation.
I would be grateful for your help :)
If you're using Mongo version 5.0+ then you can use $dateTrunc and $dateAdd to achieve this quite easily, like so:
db.collection.updateMany(
{},
[
{
$set: {
"info.startDate": {
$cond: [
{
$ne: [
{
$hour: "$info.startDate"
},
0
]
},
{
$dateTrunc: {
date: {
$dateAdd: {
startDate: "$info.startDate",
unit: "day",
amount: 1
}
},
unit: "day",
}
},
"$info.startDate"
]
}
}
}
])
For older Mongo versions this is slightly messier, you should use $dateFromParts to create the new date object, like so:
db.collection.updateMany(
{},
[
{
$set: {
"info.startDate": {
$cond: [
{
$ne: [
{
$hour: "$info.startDate"
},
0
]
},
{
$dateFromParts: {
"year": {
$year: {
$add: [
"$info.startDate",
86400000
]
}
},
"month": {
$month: {
$add: [
"$info.startDate",
86400000
]
}
},
"day": {
$dayOfMonth: {
$add: [
"$info.startDate",
86400000
]
}
},
"hour": 0,
"minute": 0,
"second": 0,
"millisecond": 0,
}
},
"$info.startDate"
]
}
}
}
])
Mongo Playground
I want to filter classes that are still on going using $match with moment js. But, the $getField doesn't work as expected.
$match: {
$expr: {
$lt: [
moment(new Date()).valueOf(),
parseInt(moment({ $getField: "classStartDate" }, 'x').add({ $getField: "numberOfWeeks"}, 'weeks').valueOf())
]
}
}
Why so complicated? Simply try this:
$match: {
$expr: {
$lt: [
"$$NOW",
{$add: ["$classStartDate", {$multiply: ["$numberOfWeeks", 1000*60*60*24*7 ]} ] }
]
}
}
As you are obviously using Mongo version 5.0, you can also use
$match: {
$expr: {
$lt: [
"$$NOW",
{ $dateAdd: { startDate: "$classStartDate", unit: "week", amount: "$numberOfWeeks" } }
]
}
}
If $$NOW does not work use moment().toDate()
I'm querying through Metabase which is connected to a Mongodb server. The field which I'm querying is nested and is a Unix timestamp. See below
{
room_data: {
"meta": {
"xxx_unrecognized": null,
"xxx_sizecache": 0,
"id": "Hke7owir4oejq3bMf",
"createdat": 1565336450838,
"updatedat": 1565336651548,
}
}
}
The query I have written is as follows
[
{
$match: {
client_id: "{{client_id}}",
"room_data.meta.createdat": {
$gt: "{{start}}",
$lt: "{{end}}",
}
}
},
{
$group: {
id: "$room_data.recipe.id",
count: {
$sum: 1
}
}
}
]
I do not get any result as the field room_data.meta.createdat is not a date (Aug 20, 2020) which I'm passing in. Here start and end are the parameters (Metabase feature) which I'm passing in the Date format. I need some help in converting those dates into unix timestamp which can then be used to filter out the results between the specific dates
If you're using Mongo version 4.0+ you can then use $toDate in you're aggregation like so:
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{
$eq: [
"$client_id",
{{client_id}}
]
},
{
$lt: [
{
$toDate: "$room_data.meta.createdat"
},
{{end}}
]
},
{
$gt: [
{
$toDate: "$room_data.meta.createdat"
},
{{start}}
]
}
]
}
}
}
])
MongoPlayground
If you're you're on an older Mongo version I recommend you either convert you're database fields to be Date type, or you convert your input into a number timestamp somehow (I'm unfamiliar with metabase).
The last option is to use $subtract as you can subtract a number from a date in Mongo, then check to see whether that date is before or after 1970-01-01T00:00:00Z. the problem with this approach is it does not consider timezones, so if your input's timezone is different than your database one or is dynamic this will be a problem you'll have to account for.
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{
$eq: [
"$client_id",
{{client_id}}
]
},
{
$gt: [
{
"$subtract": [
{{end}},
"$room_data.meta.createdat"
]
},
ISODate("1970-01-01T00:00:00.000Z")
]
},
{
$lt: [
{
"$subtract": [
{{start}},
"$room_data.meta.createdat"
]
},
ISODate("1970-01-01T00:00:00.000Z")
]
}
]
}
}
}
])
MongoPlayground
my collection in db is
plannedEndDate:{"2020-03-10T11:22:33.677+00:00"}
in controller var tdate= new Date(); [tdate is in the format 2020-03-10T14:28:22.687Z].
now,I need to check plannedEndDate is less than tdate in mongoose.
i tried,
plannedEndCmp: {
$cond: [{ $lt: ["$plannedEndDate", tdate] }, 1, 0]
}
but it is not returning true.
so should i need to trim the timestamp to compare dates in mangodb?or should i need to convert date into common format?
Not clear what you actually like to do but below command find the document or show indication:
db.collection.find(
{ plannedEndDate: { $lt: tdate } }
)
db.collection.aggregate([
{ $set: { plannedEndCmp: { $cond: [{ $lt: ["$plannedEndDate", tdate] }, 1, 0] } } },
{ $set: { plannedEndCmp_bool: { $lt: ["$plannedEndDate", tdate] } } }
])
In Aggregate group:
`
factualEndDate: {
"$dateToString": { "format": "%Y-%m-%d", "date": "$factualEndDate" }
},
In Aggregate project:
DelayedComplete: { $cond: [
{
$and: [
{ $cond: [{ $lte: [{ $max: "$data.factualEndDate" }, today] }, 1, 0] },
]
},
1,
0
]
},
`