I have a creation date attribute of a document which has a format like this: "05/03/2020" of type String.
I must extract all the documents from my system having a creation date before "05/03/2020".
I tried with:
db.MyCollection.find ({DateC: {$lte: "05/03/2020"}})
but it still returns 0.
Is there a way to compare if a date format String is before another date?
Thank you
You can use $dateFromString operator to convert $DateC to ISODate,
Make sure your input should be in ISODate format,
db.MyCollection.find([
{
$expr: {
$lte: [
{
$dateFromString: {
dateString: "$DateC",
format: "%d/%m/%Y"
}
},
ISODate("2020-03-05T00:00:00.000Z")
]
}
}
])
Playground
I am not sure with your date format, I have predicted as d/m/y, you can manage it your self if its different.
Related
In the schema of mongoDB, I am trying to store current date using date.now(), but it is storing date in UTC format. How can I change the date format in local date?
MongoDB stores dates in BSON Date type, UTC timestamp with 64-bit integer internally. What you want is store dates as local date formatting, just store them already formatted String, not Date. What you want is to see date values as local time, consider using $dateToString aggregation expression.
For example:
db.getCollection('users').aggregate([
{
$project: {
createdAt: { $dateToString: { date: '$createdAt', timezone: 'Asia/Seoul' } }
}
}
])
// { "_id": ..., "createdAt" : ISODate("2020-12-02T04:52:02.237Z") }
// -> { "_id": ..., "createdAt": "2020-12-02T13:52:02.237Z" }
Also replacing other formats later, such as: finding all dates with 'dd/mm/YYYY' format and changing them to ISO 'YYYY-mm-dd' format.
But as for the 'null' issue, this is the .js I am trying to run in MongoDB (NoSQLBooster):
use sms
db.collection1.find({
"FirstDate":null
})
.projection({})
//.sort({ _id: -1 })
//.limit(1000)
.forEach(function(doc) {
var date = doc.FirstDate
if (date == null) {
date = ''
}
})
And all I'm getting is "undefined" results. What could the problem be?
You can use update with {multi: true} to ensure all values that match are updated (not only the first one)
db.collection.update({
FirstDate: null
},
{
$set: {
FirstDate: ""
}
},
{
multi: true
})
Example here
I am using .aggregate and $match to filter dates and then $sample them. Right now I get an empty array. I am using the following code:
const result = await Event.aggregate([
{
$match: { event_added: condition },
},
{ $sample: { size: 10 } },
]);
When I use .find in the code below it works perfectly, and I get all records satisfying the condition.
const result = await Event.find({ event_added: condition });
The condition object is the following:
var condition = { $gt: start, $lt: end };
For Model.find() operations, mongoose can infer the data type based on your schema and converts the types in your query object accordingly.
So if start and end are not Date objects, mongoose will try to cast the values to Date, as specified in your Event schema.
Aggregation objects are more complex and mongoose can not automatically do type casting. If your values are not Date objects you'll have to convert them first before passing them to Model.aggregate()
Generally this should work
const condition = { $gt: new Date(start), $lt: new Date(end) }
I've a usecase in which I need to find the data of a particular month. How to get the start and end dates of given month?
Here's the sample code.
{"_id":"5e00bc55c31ecc38d023b156","heat":20,"humidity":10,"deviceId":"a-1","template":"13435158964","entryDayTime":"2019-12-23T13:08:37.841Z"},
{"_id":"5e00bbd2c31ecc38d023b155","heat":20,"humidity":10,"deviceId":"a-1","template":"13435158964","entryDayTime":"2019-12-23T13:06:26.366Z"},
{"_id":"5df4a8fb46b9da1e2c0731df","heat":88,"humidity":80,"deviceId":"a-1","template":"13435158964","entryDayTime":"2019-12-14T09:18:51.892Z"},
{"_id":"5e00b50bc127260398cf51dd","heat":20,"humidity":10,"deviceId":"a-1","template":"13435158964","entryDayTime":"2019-12-23T12:37:31.127Z"},
{"_id":"5df20e44e7c51b4bd0095af3","heat":41,"humidity":26,"deviceId":"a-1","template":"13435158964","entryDayTime":"2019-12-12T09:54:12.375Z"}
Here's my code without moment.js
Payload:
{
"deviceId":"a-1",
"year":2019,
"month":"December"
}
Collection.aggregate([
{
$match: {
"deviceId": payload.deviceId,
"entryDayTime": {
$lt: new Date(`${payload.month},${payload.year},2`).toISOString(),
$gte: new Date(`${payload.month},${payload.year},31`).toISOString()
}
}
}
])
These are the time ranges I'm getting in console(times passed in aggregate function),
2019-12-01T18:30:00.000Z
2019-12-30T18:30:00.000Z
Code with moment.js
Payload:
{
"deviceId":"a-1",
"year":2019,
"month":10
}
I've tried with moment.js too. But I'm not getting the times in the format like time format of database.
Collection.aggregate([
{
$match: {
"deviceId": payload.deviceId,
"entryDayTime": {
$lt:moment([payload.year]).month(payload.month).startOf('month').tz('Asia/Kolkata').format(),
$gte:moment([payload.year]).month(payload.month).endOf('month').tz('Asia/Kolkata').format()
}
}
}
])
Following are the timestamps I'm getting in console.
2019-11-01T00:00:00+05:30
2019-11-30T23:59:59+05:30
If moment.js is preferred, how to change the time format similar to the sample code's time format?
Just try this code:
var dated="2019-11-01T00:00:00+05:30";
var newdated= new Date(dated);
var output= newdated.toISOString();
console.log(output);
Result :
'2019-10-31T18:30:00.000Z'
The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively).
The timezone is always zero UTC offset, as denoted by the suffix "Z".
To find the data of a particular month use Date.UTC with the Date constructor to create a range:
const payload = {
"deviceId": "a-1",
"year": 2019,
"month": 11 // months start from 0 = January, so 11 = December
}
const from = new Date(Date.UTC(payload.year, payload.month, 1)).toISOString(); // "2019-12-01T00:00:00.000Z"
const to = new Date(Date.UTC(payload.year, payload.month + 1, 1)).toISOString(); // "2020-01-01T00:00:00.000Z"
then use them as follows:
Collection.aggregate([
{
$match: {
"deviceId": payload.deviceId,
"entryDayTime": {
$lt: to,
$gte: from
}
}
}
])
Working example : https://mongoplayground.net/p/jkIJdJ-L7q-
I have a collection which has a field called timestamp containing date object. I have this query:
db.articles.find({
timestamp:{
'$lte':new Date(),
'$gte': //Something to get the last week's date
}
})
Also if it is possible, Can I sort these returned documents by length of an array in this document. Here is the schema:
section: String,
title: String,
abstract: String,
url: String,
image: {
url: String,
caption: String
},
votes:{
up: [ObjectID],
down: [ObjectID]
},
comments:[ObjectID],
timestamp: Date
I want to sort the returned objects by size of difference of votes.up and votes.down. Right now I am sorting the returned objects in Javascript where this actually returns the data.
Seems the solution should look like
db.articles.find({
timestamp: {
$gte: new Date(new Date() - 7 * 60 * 60 * 24 * 1000)
}
});
it will return the previous week data i.e.,from sunday to saturday of previous week which is local where sunday is a starting day.
{
$match: {
createdAt: {
$gte: moment().day(-7).toDate(),
$lt: moment().startOf('week').toDate()
},
}
}
]);
I found a solution get the objects created in last week.
db.articles.find({timestamp:{'$lte':new Date(),'$gte':new Date(Date()-7)}})
This gets the work done. But I cant figure out how to sort the returned objects by the size of arrays.