Compare Calculated Fields to Current Date - json

Background:
We are trying to identify if notifications are due to go out against records that have configurable schedules. So, for instance, a record could have:
NotificationStep: 'week(s)'
NotificationCount: 3
StartDate: 2018-11-17
This would signal that 3 weeks after Nov 17 -- or the last time one of these notifications went out -- we need to send out a new notification.
In SQL this would involve comparing today to subquery (and possibly a union) utilizing the MAX() method.
Question:
Is there a good way to use today's date as the value by which you're comparing your calculated values against?
Something like:
myModel.find({
where:{
new Date(): {$gt: Notifications.max('date', {where: ... }
}
});

All you need is sequelize.where and sequelize.fn
Here you go :
myModel.find({
where:
sequelize.where(sequelize.fn('now') , {$gt: Notifications.max('date', {where: ... } )
});
Note : sequelize.fn('now') // <---- Give you current time from DB

Related

Ruby SQL to arel query

I am looking to create a query within the scope that will search for records that have a date less than or equal to the current date. I understand how to do this in SQL but I'm not sure how this would translate over to this. Currently all I have is this
scope :index_overdue, -> { where(active: true, end_date: nil).order(arel_table[:complete_by], arel_table[:latest_update_date], arel_table[:id]) }
I need the query to only retrieve records that have a complete_by date that is <= The current date.
I would use a beginless range to write that condition:
scope :index_overdue, -> {
where(active: true, end_date: nil, complete_by: ..Date.today)
.order(...)
}

How to write a view in couchbase for this sql statement

Let's say I have the following documents
Document 1
{
companyId: "1",
salesDate: "1425254400000" //this is UTC time as a long
}
Document 2
{
companyId: "1",
salesDate: "1425340800000" //this is UTC time as a long
}
Document 3
{
companyId: "2",
salesDate: "1425254400000" //this is UTC time as a long
}
I currently have my view set up as
function(doc, meta) { emit([doc.salesDate, doc.companyId], doc); }
Which is pulling back all 3 documents when using
?startkey=[1425254400000,"1"]&endkey=[1425340800000,"1"]
I'm not sure how to make it only pull back the sales for that date range by company id.
The sql version would be SELECT * FROM sales WHERE companyId = :companyId AND salesDate BETWEEN :rangeStart AND :rangeEnd
EDIT: I'm using the rest API.
When designing views for range queries with multiple query fields, the fixed query field(companyId) should be a prefix of the compound index and the range query field should be at the end. With the current view, Couchbase will emit every document where salesDate is within the range without considering companyId.
Reversing the order of keys will work:
function(doc, meta) {
emit([doc.companyId, doc.salesDate], doc);
}
Query:
?startkey=["1", 1425254400000]&endkey=["1", 1425340800000]
N.B. if salesDate is a string and not a numeric value, Couchbase will use lexicographic ordering to perform the range query.

Limiting and sorting by different properties on couchbase

Given a JSON document on couchbase, for example, a milestone collections, which is similar to this:
{
"milestoneDate" : /Date(1335191824495+0100)/,
"companyId" : 43,
"ownerUserId": 475,
"participants" : [
{
"userId": 2,
"docId" : "132546"
},
{
"userId": 67,
"docId" : "153"
}
]
}
If I were to select all the milestones of the company 43 and want to order them by latest first.. my view on couchbase would be something similar to this:
function (doc, meta) {
if(doc.companyId && doc.milestoneDate)
{
//key made up of date particles + company id
var eventKey = dateToArray(new Date(parseInt(doc.milestoneDate.substr(6))));
eventKey.push(doc.companyId);
emit(eventKey, null);
}
}
I do get both dates and the company Id on rest urls.. however, being quite new to couchbase, I am unable to work out how to restrict the view to return only milestones of company 43
The return key is similar to this:
"key":[2013,6,19,16,11,25,14]
where the last element (14) is the company id.. which is quite obviously wrong.
The query parameters that I have tried are:
&descending=true&startkey=[{},43]
&descending=true&startkey=[{},43]&endKey=[{},43]
tried adding companyId to value but couldn't restrict return results by value.
And according to couchbase documentation I need the date parts in the beginning to sort them. How do I restrict them by company id now, please?
thanks.
Put the company id at the start of the array, and because you'll be limiting by company id, couchbase sorts by company id and then by date array so you will be only ever getting the one company's milestone documents
I'd modify the view to emit
emit([doc.copmanyId, eventKey], null);
and then you can query the view with
&descending=true&startkey=[43,{}]
This was what worked for me previously..
I went back and tried it with end key and this seems to work - restricts and orders as required:
&descending=true&startkey=[43,{}]&endkey=[42,{}]
or
&descending=true&startkey=[43,{}]&endkey=[43,{}]&inclusive_end=true
either specify the next incremented/decremented value (based on descending flag) with end key, or use the same endkey as startkey and set inclusiveEnd to true
Both of these options should work fine. (I only tested the one with endkey=42 but they should both work)

Get count for each day in mongodb using aggregate or map reduce [duplicate]

This question already has answers here:
Count of records by Date MongoDB
(5 answers)
Closed 2 years ago.
How do i convert the below mysql query to mongodb query: SELECT count(*) as count , DATE_FORMAT( timestamp, '%d-%c-%Y' ) as day, timestamp as tm FROM visits WHERE 1 GROUP BY day ORDER BY tm. I want to use this on a nodejs so i am using native mongodb.
Get the number of pageviews for each day in mongodb where each pageview is stored along with the timestamp.
Your question lacks any effort on your part and we rarely just "give" people the answer like this, however, this one time:
NB: you cannot yet manipulate dates to cast them to different formats without some manual work yourself of picking the parts out and rejoining them. Because of this I have left out the date formatting you did and just used it as an object.
db.visits.aggregate([
{
$project: {
date: {day: {$dayOfMonth: '$timestamp'}, month: {$month: '$timestamp'}, year: {$year: '$timestamp'}},
//day: {concat: [date.day,date.mont,date.year]}
}
},
{$group: {_id: '$date', tm: '$timestamp', count: {$sum:1}}}
])
I found a working mongodb query using mapreduce which gives me the output time as unix time rather than the format I had mentioned in the question. But this was the query that was sorting the time properly. I had tried mongo group query but it did not sort according to time. The working mongo query is :
db.visits.mapReduce(
function(){
day = Date.UTC(this.timestamp.getFullYear(), this.timestamp.getMonth(), this.timestamp.getDate());
emit({day: day}, {count: 1});
},
function(key, values) {
var count = 0;
values.forEach(function(v) {
count += v['count'];
});
return {count: count};
},
{
out : {inline:1},
sort:{_id:1}
}
);

Ordering invoice numbers and letters in MySQL

I'm having problems with SQL sorting results of a query from my MySQL database. I need a way to sort invoice numbers mixed with letters and a multi digit number.
Format is: ${optional-prefix}${number part}${optional-postfix} and they are all stored in Varchar(32). It is not an option to change the number format, because the values are imported from multiple systems.
What i want to sort: (unsorted)
IoCustTextNoNumber
Io-700
IO39ABC
IO-137-kk
IO-037-kk
201-ib
201
38-kk
036
12
11-KE
IO-37-kk
00001342
IO-36-kk
11-KEk
13
035
37-kk
200
Io-701
Expected result: (sorted)
11-KE
11-KEk
12
13
035
036
37-kk
38-kk
200
201
201-ib
00001342
IO-36-kk
IO-037-kk
IO-37-kk
IO-137-kk
Io-700
Io-701
IO39ABC
IoCustTextNoNumber
Can anyone help me with a solution?
MySQL is not going to do that. You can build a custom sort in something like PHP and you do a for loop and assign things to a position. Or, You can select all that begin with lo and then update all of those to put lo into another column.
In php you could do something like:
foreach($data => row){
$test = strpos('-', $row); // If this is successful than it has a dash in the string, and it goes towards the front.
if(!$test) { // If its not a test does it begin with a number.
if($row[0] >= 0){
// Do whatever you need
}
}
}