Mongodb searching date ranges within a list of dates - mongodb

In mongodb,
if I have a date, and I want to query for records that have a date later than the provided date I can do this:
collection.find({datefield:{$gt:somedate}})
And if I want to find records between a date range, I can do an $and with lt and gt.
But say that my datefield is actually datefields, a list of dates. And say that there are the following records for datefield
datefields = [june 1, 2015 hhmmss, june 2, 2015 hhmmss, june 14, 2015 hhmmss]
datefields = [june 1, 2015 hhmmss, june 3, 2015 hhmmss, june 8, 2016 hhmmss, june 17, 2015 hhmmss]
How would I construct the search to fetch for all records whose dates are between say june 3 and june 7, so that I only get the second record. And if ranges are not possible, can I do just a single search for june 3, 2015 while disregarding the hhmmss?

I think this will solve what you're asking. Use an aggregate operation to unwind your arrays and treat each element as a separate value in a document.
db.collection.aggregate( [
{ $unwind : { "$datefields" } },
{ $match : { datefields : { $gt : ISODate("2015-06-02T00:00:01Z"), $lte : ISODate("2015-06-03T23:59:59Z")} } }
])
That alone will give you an "exploded view" of your array results, with one document per array element that matches. If you want to collapse it down you can add a $group stage.
If this isn't what you're asking could you give a bit more detail?
For the second half of your question regarding "disregarding the hhmmss", there are a number of questions already answered on SO about that. Check out Query Mongodb on month, day, year... of a datetime

Related

get a excluded day in a the month

I want to get all the data from the month in mongodb
lets say i want to get all the data from September, except 23 Sep
i think of
createdAt 1 sep AND createdAt not in 23,24 sep
but it only execute the createdAt not in 23,24 sep
is there other ways?
db.getCollection('myTest').find({
"$and":[{
createdAt:{ "$gte": ISODate("2019-09-01T16:00:00.000Z")},
createdAt:{ "$nin": [ISODate("2019-09-23T16:00:00.000Z"), ISODate("2019-09-24T16:00:00.000Z")]}
}]
})
db.test.aggregate([{$project:{date:"$date",month:{$month:"$date"},year:{$year:"$date"}}},{$match:{$and:[{date:{$nin:[ISODate("
2019-09-23T00:00:00Z")]}},{month:9},{year:2019}]}},{$project:{_id:1,date:"$date"}}])
])
To get the month number $month,$year operator gives month and year number
$nin for not in date and check month and year number to get particular month in a year
$project the required values

How to pass a date into a ColdFusion collection to be searched

I'm using a ColdFusion collection to search events and I need to pass a date into the collection as a "mmm" so it can be searched. Every time I try I get an error.
custom4="DateFormat(start_date, "mmm")"
Update:
I'm trying to search "month" of the current year
You should use the above code like
custom4=dateFormat(start_date, "mmm")
(Remove the outer double quotes)
Quotes aren't the problem and the suggestion of removing them will actually cause an error. The problem is DateFormat() can't be applied to an entire query column. It's only capable of operating on a single value.
It would help to have more context about what you're trying to achieve, to determine the best approach.
If you want to find items dated in July of a specific year (i.e. July 2019) - then storing the full date, and searching for a date range, is probably a better way to go
If you want to find items dated in July of ANY year, then it's simpler to extract a month number within your SQL query, and store it in the collection. Then you need only search for a number.
Date Range Search
To search for a specific month/year, like July 2019, populate the collection with a timestamp field from your SQL query. Add the suffix _dt to the custom field name so it's treated as a date field
cfindex( query="yourQuery"
, collection="yourCollection"
, action="Update"
, type="Custom"
, Start_Date_dt="yourTimeStampColumn"
, ...
);
In the search criteria, use the date range July 1 through August 1, 2019 (yes - August 1st). Dates must be formatted for Solr, which expects YYYY-MM-DDThh:mm:ssZ. NB: Dates should be in UTC (not local time).
cfsearch (name="searchResults"
, collection="yourCollection"
, criteria=' start_date_dt:[2019-07-01T04:00:00Z TO 2019-08-01T04:00:00Z}'
);
Explanation/Notes
[ and } - Brackets indicates a range (i.e. from dateX TO dateY)
[ - Square bracket means inclusive (i.e. include July 1st)
} - Curly bracket means exclusive (i.e. exclude August 1st)
Field names should be in lower case
Month Number Search
To search for a specific month in any year, like July, extract the month number within your SQL query. (The exact syntax will be DBMS specific. You didn't mention which one you're using, so see your database's documentation on date functions.) Add the suffix _i to the custom field name so it's handled as an integer
cfindex( query="yourQuery"
, collection="yourCollection"
, action="Update"
, type="Custom"
, monthNumber_i="theMonthNumberColumn"
, ...
);
Then simply search for the desired month number, i.e. 7 - July
cfsearch ( name="searchResults"
, collection="yourCollection"
, criteria=' monthnumber_i:7 '
);
Full Example
Sample Query
sampleData = queryNew("MyID,Start_Date,MonthNumber"
, "integer,timestamp,integer"
, [{MyID=10, Start_Date="2019-06-30 12:30:00", MonthNumber=6}
, {MyID=20, Start_Date="2019-07-01 00:00:00", MonthNumber=7}
, {MyID=30, Start_Date="2019-07-01 16:30:00", MonthNumber=7}
, {MyID=40, Start_Date="2019-07-31 23:50:00", MonthNumber=7}
, {MyID=50, Start_Date="2019-08-01 00:00:00", MonthNumber=8}
]);
Create Collection
cfcollection ( action="create", collection="MyCollection");
Update Collection
cfindex( query="sampleData"
, collection="MyCollection"
, action="Update"
, type="Custom"
, key="MyID"
, title="SampleData"
, MonthNumber_i="MonthNumber"
, Start_Date_dt="Start_Date"
, body="MyID"
);
Find July, by month number
cfsearch ( name="monthNumberResults"
, collection="MyCollection"
, criteria=' monthnumber_i:7 '
);
// results
writeDump( var=monthNumberResults, label="Month Number Search" );
Find July 2019, by date range
// Search range: July 1 to August 1, 2019
fromDate = "2019-07-01";
toDate = dateAdd("m", 1, fromDate);
// Format dates for Solr
// Note: DateTimeFormat uses "n" for minutes. Valid in CF2016 Update 3 or higher
fromDate = dateTimeFormat( dateConvert("local2UTC", fromDate), "yyyy-mm-dd'T'HH:nn:ss'Z'");
toDate = dateTimeFormat( dateConvert("local2UTC", toDate), "yyyy-mm-dd'T'HH:nn:ss'Z'");
cfsearch ( name="dateRangeResults"
, collection="MyCollection"
, criteria=' start_date_dt:[#fromDate# TO #toDate#} '
);
// results
writeDump( var=dateRangeResults, label="Date Range Search" );

mongodb indexable $and query possible?

I'm developing an app using a MongoDB database that needs to check for items enabled for today's particular weekday.
Items can be enabled for any individual days of the week. (eg: Monday and Wednesday, or Tuesday and Thursday and Saturday, every day, whatever)
I was going to do this:
var currentWeekDay = Math.pow(2,new Date().getDay());
Therefore
Sunday === 1
Monday === 2
Tuesday === 4
Wednesday === 8
...
Saturday === 64
An example item might be like this
{_id:'blah', weekDays:127}
Now I want to query all items that are enabled for today...
MongoDB has an operator $and, but that's only for logical operations.
It has $bitsAnySet, but it looks like it's only implemented in 3.16.
https://jira.mongodb.org/browse/SERVER-3518
I'm running MongoDB v2.6.10.
So I'm wondering how to come up with a sensible indexable query.
Maybe
{_id:'blah', w0:1, w1:1, w2:1, w3:1, w4:1, w5:1, w6:1} //every day
{_id:'blah', w0:1, w1:0, w2:0, w3:0, w4:0, w5:0, w6:1} //Sat and Sun
That would be easily indexable. Can anyone think of a more terse way of doing it?
One option would be storing days as an array of integers:
{ '_id' : '1' , 'weekDays' : [0,1,2,3,4] } // mon-fri
{ '_id' : '2' , 'weekDays' : [5,6] } // sat-sun
Then you could create a simple index on weekDays field:
db.collection.createIndex({ weekDays : 1 })
And querying would also be pretty simple:
db.collection.find({weekDays : 2}) // wed

Finding date within date range

I am trying to find all documents with date field within date range as shown below in my Meteor app, but for some reason it is always returning empty records, can someone please tell me what I might be doing wrong / missing here? Thanks
Sample document:
_id: "tMSfNq9JR85XDaQe5"customerid: "QDGvBQhS6vYgZtnRr"date: Sun Dec 07 2014 19:50:21 GMT+0800 (HKT)description: "Test"
Tried using queries from Chrome console as follows:
Custlog.find({date: {$gt: new Date(2014, 12, 1) , $lt: new Date(2014, 12, 10) }}).fetch()
Custlog.find({date: {$gt: new Date(01/12/2014) , $lt: new Date(10/12/2014) }}).fetch()
In their infinite wisdom, the implementors of the JavaScript Date Object made the month field zero indexed. So, January 1 is new Date(2014, 0, 1) and December 1 is new Date(2014, 11, 1). What you have Date(2014, 12, 1) is actually January 1, 2015.
Similarly, new Date(01/12/2014) is equivalent to dividing 1 by 12 and then dividing that by 2014 and then sending that as a number to the date object which is zero so it should give you the Unix Epoc, which in your time zone (GMT+08) is January 1, 1970.

$week mongodb to datepart(wk)

I'm exporting aggregated data to MS SQL server from mongodb
mongo's $week does not evaluate to the same week as T-SQL datepart(wk, ) or datepart(isowk, ).
Does anyone know how to test the mongodb $week function so I can do some comparisons and see how best to resolve this issue?
Any help would be appreciated.
As far as I can see the differences fall into two main areas, the plain part being described in the documentation:
Weeks begin on Sundays, and week 1 begins with the first Sunday of the year. Days preceding the first Sunday of the year are in week 0. This behavior is the same as the ā€œ%Uā€ operator to the strftime standard library function.
So the general concept here is that the value returned will be between 0 and 53 inclusive with week 0 being defined as the first week when the days are before Sunday.
So to paraphrase ( because the documentation gets the days wrong ) from the technet source for "datepart":
January 1 of any year defines the starting number for the week datepart, for example: DATEPART (wk, 'Jan 1, xxxx') = 1, where xxxx is any year.
And then (corrected):
The following table lists the return value for week and weekday datepart for '2007-04-21 ' for each SET DATEFIRST argument. January 1 is a Saturday in the year 2007. April 21 is a Saturday in the year 2007. SET DATEFIRST 7, Sunday, is the default for U.S. English.
So where you had documents like this:
{ "date" : ISODate("2007-01-01T00:00:00Z") }
{ "date" : ISODate("2006-12-31T00:00:00Z") }
{ "date" : ISODate("2006-01-01T00:00:00Z") }
The $week operator would return such as this:
{ "date" : ISODate("2007-01-01T00:00:00Z"), "week" : 0 }
{ "date" : ISODate("2006-12-31T00:00:00Z"), "week": 53 }
{ "date" : ISODate("2006-01-01T00:00:00Z"), "week" : 1 }
January 1st in 2006 was a Sunday and is considered the start of week 1, but where it was a Saturday it would be week 0 of 2007. The 31st of December in the previous year is Week 53.
In contrast the DATEPART considers Jan 1st 2007 and Dec 31st 2006 to be in Week 1 as the week ending on the first Sunday of the year. The Sunday is the default US English value but may differ and can in fact be set via SET DATEFIRST
So both have different opinions of where a date belongs in terms of the week of the year, but the general difference will be one with the other consideration days falling at the end of the previous year.