Based on the below query return result I want to filter the month and ther year.
For example I only want data for the month of March.
db.SBM_USER_DETAIL.aggregate([
{
$project: {
join_date: '$JOIN_DATE'
}
}
]).map(
function(d) {
d.join_date = moment(d.join_date).locale('es').tz("Asia/Kolkata").format();
return d
})
How to use the returned formatted value of join_date inside the MongoDB aggregation query?
MongoDB's ISODate is very similar to the javascript Date class. If you have a date range in the Kolkata timezone, and want to filter by that, instantiate a pair of Date objects to define the range, before running the find.
For this instance, to return all join_date values that fall within March 2017, converted to the Kolkata (UTC-07:00) timezone, filter for date greater than or equal to midnight March 1 and less than midnight April 1, then convert the results using moment:
var first = new Date("2017-03-01T00:00:00-07:00");
var last = new Date("2017-04-01T00:00:00-07:00");
db.SBM_USER_DETAIL.find(
{join_date:{$gte: first, $lt: last}}, //filter based on join_date
{join_date:1,_id:0} // only return join_date, omit this if you need all fields
).map(
function(d) {
d.join_date = moment(d.join_date).locale('es').tz("Asia/Kolkata").format();
return d;
}
);
Related
I wondered if anyone could help. I have a script where I am pulling out data from a spreadsheet list, where this is a match for this week (basically an events list, to produce a weekly agenda). I will use a for loop to increment the days to add on, but I am just trying to make it work for one day for now...
The first column is the data in format dd/mm/yyy
I am trying to take today's increment by 1 and then search through the list to find a match. The searching etc, I can make work, but the date part is just not playing. I wondered if anyone could advise.
E.g. Date Column A:
06/07/2021
06/07/2021
01/11/2021
01/11/2021
01/11/2021
01/11/2021
02/09/2021
02/09/2021
var selectedDate = row[0];
selectedDate = Utilities.formatDate(new Date(selectedDate), "GMT+1", "dd/MM/yyyy");
var currdate = new Date();
currdate = Utilities.formatDate(new Date(selectedDate), "GMT+1", "dd/MM/yyyy");
var daystochange = 1;
var newdate = new Date(currdate.getFullYear, currdate.getMonth, currdate.getDay+daystochange );
Could anyone help?
Thanks
Only use Utilities.formatDate() to output dates, not to work with dates.
The JavaScript date object has all you need to work with dates and compare. When you use the Utilities function it converts it to a string, and so you lose all the functionality of the Date object.
Also bear in mind that if you have dates, that are formatted as dates in your sheet, they will automatically be returned as Date objects.
For example, if your sheet has a date in cell A1
var date = Sheet.getRange("A1").getValue()
date instanceof Date // true
Once you have your date, if you want to add one day to it, you can take an approach similar to what you have already done:
var selectedDate = new Date(2021, 1, 15)
var newdate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate() + 1);
console.log(newdate) // Tue Feb 02 2021 00:00:00
Note - use getDate to return the day of the month, getDay only returns day of the week.
To check if two dates are the same, you can write a function to compare:
function isSameDate(a, b) {
return a instanceof Date &&
b instanceof Date &&
a.getYear() === b.getYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate()
}
This function will return true if the dates are the same.
Reference
Date
assuming I have the following nested document structure, where my document contains nested routes with an array of date time values.
{
property_1: ...,
routes: [
{
start_id: 1,
end_id: 2,
execution_times: ['2016-08-28T11:11:47+02:00', ...]
}
]
}
Now I could filter my documents that match certain execution_times with something like this.
query: {
filtered: {
query: {
match_all: { }
},
filter: {
nested: {
path: 'routes',
filter: {
bool: {
must: [
{
terms: {
'routes.execution_times': ['2016-08-28T11:11:47+02:00', ...]
}
},
...
]
}
}
}
}
}
}
But what if I would like to filter my documents based on execution dates. What's the best way achieving this?
Should I use a range filter to map my dates to time ranges?
Or is it better to use a script query and do a conversion of the execution_times to dates there?
Or is the best way to change the document structure to contain both, the execution_date and execution_time?
Update
"The dates are not a range but individual dates like [today, day after tomorrow, 4 days from now, 10 days from now]"
Well, this is still a range as a day means 24 hours. So if you store your field as date time, you can use leverage range query : from 20-Nov-2010 00:00:00 TO 20-Nov-2010 23:59:59 with appropriate time zone for a specific day.
If you store it as a String then you will lose all the flexibility of date maths and you would be able to do only exact String matches. You will then have to do all the date manipulations at the client side to find exact matches and ranges.
I suggest play with range queries using Sense plugin and I am sure it will satisfy almost all your requirements.
-----------------------
You should make sure that you use appropriate date-time mapping for your field and use range filter over that field. You don't need to split into 2 separate fields. Date maths will allow you to query just based on date.
This will make your life much easier if you want to do aggregations over date time field.
Reference:
Date Maths:
https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math
Date Mapping : https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html
Date Range Queries:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
I'm trying to get a specific range of documents, based on when they were created. What I'm trying to do is something like:
/getclaims/2015-01
/getclaims/2015-02
...
that way a user can browse through all records based on the selected month.
In my database I'm not storing a created_at date, but I know mongodb stores this in the objectid.
I found that I can get records like this:
db.claims.find({
$where: function () { return Date.now() - this._id.getTimestamp() < (365 * 24 * 60 * 60 * 1000) }
})
of course that doesn't filter based on a specific month, but only within a certain time limit.
What would be a possible way of limited a query based on a specific month, using the Timestamp from the objectid's?
I'm using mongoose, but it's probably a good idea to start in mongo shell itself.
Based on the function borrowed from the answer to this question - https://stackoverflow.com/a/8753670/131809
function objectIdWithTimestamp(timestamp) {
// Convert date object to hex seconds since Unix epoch
var hexSeconds = Math.floor(timestamp/1000).toString(16);
// Create an ObjectId with that hex timestamp
return ObjectId(hexSeconds + "0000000000000000");
}
Create a start and an end date for the month you're looking for:
var start = objectIdWithTimestamp(new Date(2015, 01, 01));
var end = objectIdWithTimestamp(new Date(2015, 01, 31));
Then, run the query with $gte and $lt:
db.claims.find({_id: {$gte: start, $lt: end}});
I have a fusion table with two date_time columns. The fist one is the start date (Startdatum) and in the other column is the end date (Einddatum).
I want to do a query with the current date, and only show the KML-lines on a map where the current date lies between the start and end date.
I tried to use the code below to create a string with a date format:
var time_date = new Date();
var day = time_date.getDate();
var month = time_date.getMonth()+1;
var year = time_date.getFullYear();
var date = (year+"."+month+"."+day);
To show the KML-lines on the map I tried to use the following code:
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col2",
from: "1mOMP1seJq4FdiNTugsfylZaJc8sKcSlfJKUuTJjv",
where: "'Startdatum' <= date AND 'Einddatum' >= date"
},
options: {
styleId: 2,
templateId: 2
}
});
Unfortunatly the map shows all the KMS-lines regardless what date is in one of the columns.
What am I doing wrong?
the where-clause is wrong, it has to be
where: "Startdatum <= '"+date+"' AND Einddatum >= '"+date+"'"
the date-format seems to be wrong. Although the used format yyyy.MM.dd is defined in the documentation, it doesn't work. The format yyyy-MM-dd currently works for me(but it's not defined in the documentation).
var date = (year+"-"+month+"-"+day);
(in case that day and month be less than 10 they wouldn't match the pattern, but that doesn't seem to be an issue)
Beyond that: when you fix these 2 mentioned parts it currently works(for me), but I've tried it a couple of hours ago and got unstable results.
I have the following data.
{
deviceID: 186,
date: "2014-3-15"
}
{
deviceID: 186,
date: "2014-3-14"
}
{
deviceID: 186,
date: "2014-3-13"
}
And some lower dates, like 2014-3-9 , 8 ,7 ,6 etc.
When doing a db.coll.remove({date:{$lte:"2014-3-5"}})
Mongo removes the 15,14,13 aswell, but keeps single digit day dates. Is this maybe due to the date is a string?
I dont know how else to format the date so I can remove all dates below a certain date.
It is supposed to be a cleaning process, removing all documents with a date lower than specified.
Its because the date field you are querying on is a string filed and not a Date(). In your mongo documents instead of a custom date string, insert javascript date objects into date field.
like
{ deviceID: 186,,"date": new Date(2012, 7, 14) }
and when you execute the remove do it like
db.coll.remove({date:{$lte:new Date(2012, 7, 14)}})
If you want to remove data from MongoDB from the date less than specified, you MUST make sure of the date.
Easiest way for you to check whether you are inputting the right format is to test it before you use it in your query.
For example if you want to get current date in ISODate in Mongo shell, just type new Date and you will get the current date in Mongo.
I've tried the following in the Mongo shell:
new Date(2017, 11, 1)
and it returns
ISODate("2017-11-30T16:00:00Z")
which is not what I wanted.
What I want is to delete data before 1 November 2017.
Here's what works for me:
new Date("2017-11-01")
and it returns:
ISODate("2017-11-01T00:00:00Z")
Which is what I wanted.
This is because you are storing your data in a wrong format. You have a string an string
'15' is smaller than string '5'. Convert your strings in the beginning to date (read here how to use dates in mongo).
And only than you can use it to properly compare your dates:
db.coll.remove({
date:{
$lte : new Date(2012, 7, 14)
}
})
The reason for this is is your dates are strings.
So in a lexical sense when comparing strings "2014-3-5" is greater than "2014-3-15", as what is being compared is that "1" is less than "5".
Fix your dates as real ISO Dates, or you will forever have this problem.
Batch convert like this, assuming "year" "month" "day" in format:
db.eval(function(){
db.collection.find().forEach(function(doc) {
var d = doc.date.split("-");
var date = new Date(
"" + d[0] + "-" +
( d[1] <= 9 ) ? "0" + d[1] : d[1] + "-" +
( d[2] <= 9 ) ? "0" + d[2] : d[2]
);
db.collection.update(
{ "_id": doc._id },
{ "$set": { "date": date }
);
});
})
That makes sure you get the right dates on conversion.