Amazon DynamoDB: How to search for range of dates? - date

I have a DynamoDB and some items there have a date field. The date field is a string of the format {YYYY-MM-DD}. What should I have to write that the DB will retrieve all items which date field is between a start date and an end date?
This is my code:
function searchFile(from_date, until_date) {
AWS.config = new AWS.Config({accessKeyId: '***', secretAccessKey: '***', region: '***'});
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
"TableName" : '***',
FilterExpression: "Date_ = :date",
ExpressionAttributeValues: {
// What should I write here?
},
}
dynamodb.scan(params, function(err,data) {
if (err) {
console.log(err);
}
console.log(data);
})
}

The DynamoDB stores dates as String. You can use BETWEEN operator to get the range of dates.
createdate - is the attribute name
FilterExpression: "createdate BETWEEN :date1 and :date2",
ExpressionAttributeValues: {
":date1": "2010-05-05",
":date2": "2011-10-04",
}
Date S (string type). The Date values are stored as ISO-8601 formatted
strings.
BETWEEN : Greater than or equal to the first value, and less than or
equal to the second value.

Related

Aurelia converted values and dataTables

I'm using DataTables jQuery plugin in Aurelia component. using column ordering and it works well excluding columns with dates.
Inside this columns I'm using value-convertet to convert isoString value to DD.MM.YYYY date format. Value covreters usage leads to wrong date column ordering, but if I'm not using value-converter everything works well. Unfortunately I didn't find any reason why it doesn't work correctly.
Wrong filtering example: I see rows with date value like 27.05.2010 before 18.05.2017
DataTables init:
$('#searchResultsTable').dataTable({
destroy: true,
searching: false,
paging: false,
orderMulti: false,
order: [[ 2, "desc" ]],
dateFormat: 'DD.MM.YYYY'
});
Date value converter (using moment library):
import * as moment from 'moment';
export class DateFormatValueConverter {
toView(value: Date, format: string): string {
if (value) {
return moment(value).format(format);
}
return null;
}
fromView(value: string, format: string): Date {
var isValid = moment(value, format, true).isValid();
if (value && isValid) {
return moment(value, format).toDate();
}
return null;
}
}
UPDATE:
Ordered with value converter
Orderd without ValueConverter(ordered like it should 2017 year value on the top)
The ordering mechanism of the data table is working correctly - it's your understanding that's off I'm afraid.
When ordering in descending order, any that start with 27. will be at the top, as they're the "biggest". Within all the dates that start with 27, it'll order on the month, biggest first, and then the year.
The order mechanism doesn't realise you're ordering a date so we need to look at the Custom Sorting Plugins;
https://www.datatables.net/plug-ins/sorting/
And specifically the Date-De plugin - as that matches your date format;
https://www.datatables.net/plug-ins/sorting/date-de
An example taken from the above page;
$('#example').dataTable( {
columnDefs: [
{ type: 'de_datetime', targets: 0 },
{ type: 'de_date', targets: 1 }
]
});

Store and Retrieve Date in dd MMM yyyy format in MongoDB model

I have a MongoDB model that contains a Date field whose type is defined as Date.now. Any date is converted to ISO date format. Inside the model the date is defined as :
xDate : {
type: Date.now,
required: true
}
I pass the current Date as :
var d = new Date();
var temp = d.toISOString();
var subStr = temp.substr(10,temp.length - 1);
var curDate = temp.replace(subStr, "T00:00:00.000Z");
console.log(curDate);
However the date is stored as an ISO String inside the MongoDB schema. I try to query it using Mongoose using the following query:
X.
find({
xDate: curDate
})
.exec(function(err, doc) {
var response = {
status : 200,
message : doc
};
if (err) {
console.log('Error');
response.status = 500;
response.message = err;
} else if (!doc) {
console.log("Documents against the date not found in database" ,curDate);
response.status = 404;
response.message = {
"message" : "Documents not found for " + curDate
};
}
res
.status(response.status)
.json(response.message);
});
I keep getting a blank json array inspite of the data being there. Inside the table the xDate is stored as YYYY-MM-DD format.
The date inside mongo is not stores in ISO string. If you save your model as Date.now, it will save a new Date object, not an ISO string. So one easy way of querying is to query by new Date() object.
Also note that your query is hard to be true, since you will have a hard time getting the exactly same date as your data is stored. I think better option for you is using $lt or $gt filters.
New query should look something like:
let currDate = new Date()
// change the date using class methods
X.find({
xDate: {$lt: currDate}
}).exec...

Compare date (moment.js) in MongoDB

I want to compare date from MongoDB and my date.
Also i read this and this post and I did not find an answer.
My Code :
today: function() {
var today = moment().format();
return Posts.find({createdAt : { $gte : today}}) // show posts created in "future" , so this function must return nothing
},
createdAt = moment().format();// in MongoDB
As a result this construction doesn't work, but if i compare lie this :
var today = moment().format();
var daystart = moment().startOf('day').format();
if (daystart > today){
console.log ("YES");
}
else if (daystart < today)console.log ("NO");
Return
"NO"
Anybody help ?
EDIT :
today: function() {
var today = moment().toDate();
var daystart = moment().startOf('day').toDate();
// console.log(today + daystart);
return Posts.find({createdAt : { $gt : today}})
},
week: function() {
var today = new Date();
return Posts.find({createdAt : { $lt : today}})
},
month: function() {
var today = new Date();
return Posts.find({createdAt : { $ne : today}})
}
createdAt = new Date();
The .format() method is a display helper function which returns the date string representation based on the passed token argument. To compare the date from MongoDB with the the current date and time, just call moment() with no parameters, without the .format() method and get the native Date object that Moment.js wraps by calling the toDate() method:
today: function() {
var now = moment().toDate();
return Posts.find({createdAt : { $gte : now }});
}
Convert date to MongoDB ISODate format in JavaScript using Moment JS
MongoDB uses ISODate as their primary date type. If you want to insert a date object into a MongoDB collection, you can use the Date() shell method.
You can specify a particular date by passing an ISO-8601 date string with a year within the inclusive range 0 through 9999 to the new Date() constructor or the ISODate() function. These functions accept the following formats:
new Date("<YYYY-mm-dd>") returns the ISODate with the specified date.
new Date("<YYYY-mm-ddTHH:MM:ss>") specifies the datetime in the client’s local timezone and returns the ISODate with the specified datetime in UTC.
new Date("<YYYY-mm-ddTHH:MM:ssZ>") specifies the datetime in UTC and returns the ISODate with the specified datetime in UTC.
new Date() specifies the datetime as milliseconds since the Unix epoch (Jan 1, 1970), and returns the resulting ISODate instance.
If you are writing code in JavaScript and if you want to pass a JavaScript date object and use it with MongoDB client, the first thing you do is convert JavaScript date to MongoDB date format (ISODate). Here’s how you do it.
var today = moment(new Date()).format('YYYY-MM-DD[T00:00:00.000Z]');
console.log("Next day -- " + (reqDate.getDate() + 1))
var d = new Date();
d.setDate(reqDate.getDate() + 1);
var tomorrow = moment(d).format('YYYY-MM-DD[T00:00:00.000Z]');
You can pass today and tomorrow object to MongoDB queries with new Date() shell method.
MongoClient.connect(con, function (err, db) {
if (err) throw err
db.collection('orders').find({ "order_id": store_id, "orderDate": {
"$gte": new Date(today), "$lt": new Date(tomorrow)}
}).toArray(function (err, result) {
console.log(result);
if (err) throw err
res.send(result);
})
})

How do I write a query that returns all documents whose date is between two dates?

I have a database of events and I would like to find all events in a given month. The approach I'm taking is to find all events whose date is greater than, say February 1, 2015, and less than or equal to February 28, 2015. Here is the code I have:
var start = '2015-02-01T00:00:00:000Z';
var end = '2015-02-28T00:00:00:000Z';
Event
.find({
'start_date': {
'$gte' : start,
'$lte' : end
}
})
.sort({start_date: 1})
.exec(function (err, data) {
if (err) {
console.log('ERROR = ' + err);
} else {
month = data;
console.log('month' = JSON.stringify(month));
... // do other stuff
}
});
My query always comes back empty, even though I have records in my database that should be returned. What am I doing wrong?
UPDATE--------------------------------------------------------
Here is the schema I'm using:
var eventSchema = mongoose.Schema({
title : String,
details : String,
start_date : Date,
end_date : Date,
created : {
type: Date,
default: Date.now
}
});
A good explanation of how to get around this issue can be found in the article Querying for a Date Range (Specific Month or Day) which essentially suggests that you construct Date instances representing the start and end of the month used to do the range query (bearing in mind that in the Date() constructor, the month argument is 0-based index i.e. starts counting at 0, not 1. On the other hand, the days start counting at 1):
var start = new Date(2015, 1, 1);
var end = new Date(2015, 2, 1);
Event.find({
'start_date': {
'$gte' : start,
'$lt' : end
}
})
.sort({start_date: 1})
.exec(function (err, data) {
if (err) {
console.log('ERROR = ' + err);
} else {
month = data;
console.log('month' = JSON.stringify(month));
... // do other stuff
}
});
You could also try querying using the ISODate and see if it makes a difference:
'start_date': {
$gte: ISODate("2015-02-01T00:00:00.000Z"),
$lt: ISODate("2015-02-28T00:00:00.000Z")
}

Date Filter in sapui5

I have used two date controls to filter a row repeater as,
oF_cell5 = new sap.ui.commons.layout.MatrixLayoutCell({id:"F05",colSpan : 2});
var oCreateFrom = new sap.ui.commons.DatePicker("EV_AE_DATE1",
{width:"150px",placeholder:"Created From",
change:function(oEvent){
oController.onChangeFilterValue(oEvent);}
})
oF_cell51 = new sap.ui.commons.layout.MatrixLayoutCell({id:"F051",colSpan : 2});
var oCreateTill = new sap.ui.commons.DatePicker("EV_AE_DATE2",
{width:"150px",placeholder:"Created Till",
change:function(oEvent){
oController.onChangeFilterValue(oEvent);}
});
Now i have a rowrepeater in which one of the column is CreatedOn date like..,,
new sap.m.HBox({
items:[new sap.ui.commons.TextView({text:"Created on:"}),
new sap.ui.commons.TextView("TV11")
.bindProperty("text",
{
path: "CM_EventList>CREATEDON",
type: new sap.ui.model.type.Date({pattern:"MMM dd, yyyy",
source : {pattern : "dd.MM.yyyy"}})
})]
}),
And in the controller i have written this code as....,,
onInit: function() {
var model = new sap.ui.model.json.JSONModel("eventlist.json");
model.setData();
sap.ui.getCore().setModel(model,"CM_EventList");
},
onChangeCmFilterValue : function(oEvent){
var CM_FDATEVAL = sap.ui.getCore().byId("EV_AE_DATE1").getValue();
var CM_TDATEVAL = sap.ui.getCore().byId("EV_AE_DATE2").getValue();
var CM_Date = new sap.ui.model.Filter('CM_EventList>CREATEDON',
sap.ui.model.FilterOperator.BT,CM_FDATEVAL,CM_TDATEVAL);
var oCM_VBOX1 = sap.ui.getCore().byId("EV_CM_VBOX");
var oCM_RR1 = sap.ui.getCore().byId("EV_AE_ROWREPEATER");
oCM_RR1.bindRows('CM_EventList>/eventlist',oCM_VBOX1,null,[CM_Date]);
},
And the eventlist is my seperate json file which has date values as
{
"eventlist": [
{
"CREATEDON": "10.07.2014",
},
{
"CREATEDON": "10.08.2014",
},
.......
and so on..........
Now if select a date range from my date controls then the row repeater should show the records which are between the range of dates as in my json.
But the filter is not working.
Please Help me on this.
Thanks
Sathish
First of all, use the DatePicker Control for date fields in your view if you aren't using it already.
You can obtain the value of your date picker as a Date object using the method GetDateValue(). You can then use these date objects to create a filter for a datetime field of your data model.
var dateFrom = this.getView().byId("filterDateFrom").getDateValue();
var dateTo = this.getView().byId("filterDateTo").getDateValue();
if (dateFrom != null && dateTo != null) {
filter = new sap.ui.model.Filter(
"CM_EventList>CREATEDON",
sap.ui.model.FilterOperator.BT,
dateFrom,
dateTo
);
}
By the way: Note that both date objects will actually represent the moment at the beginning of the day (0:00:00) while the timestamps in your database will often be some point in time throughout the day. So when you want to search between two dates inclusively, you need to add one day to dateTo:
dateTo.setDate(dateTo.getDate() + 1);
Another problem you might or might not have to deal with are timezones... and of course all the other falsehoods programmers believe about time.
I think you should check the value of the following. The format should be different than your json value "CREATEDON": "10.08.2014".
var CM_FDATEVAL = sap.ui.getCore().byId("EV_AE_DATE1").getValue();
var CM_TDATEVAL = sap.ui.getCore().byId("EV_AE_DATE2").getValue();
Please try create a DatePicker with:
type: new sap.ui.model.type.Date({pattern: ""yyyy-MM-dd""})
Edit: to use Date as filter
var CM_FDATEVAL_DATE = new Date(sap.ui.getCore().byId("EV_AE_DATE1").getValue());
var CM_TDATEVAL_DATE = new Date(sap.ui.getCore().byId("EV_AE_DATE2").getValue());
Regards,
Allen