ArangoDB IS_DATE AQL Function - validation

I have a number of items in a collection that have a dateDue field on them. Some have this dateDue field set to an ISO8601 date, and others have null, and some others have a blank string. I want to do the following:
filter DATE_COMPARE(DATE_NOW(), dateDue, "years", "days")
However, if dateDue is null or a blank string this throws an error. I can add this to solve it:
filter w.dateDue != null and w.dateDue != ""
filter DATE_COMPARE(DATE_NOW(), dateDue, "years", "days")
But that only covers null values and blank strings. Sure this may be enough, but I would like to ensure that any record that does not have a valid date for the dateDue field is excluded. I was expecting to see an IS_DATE function for Arango, but I couldn't find one in the manual anywhere. Any ideas?

There is currently no IS_DATE function or something similar in AQL, so using filters as above is definitely one way to do it.
To make it a bit easier in the future, an IS_DATESTRING AQL function has been added in the 2.8 branch today. This will allow writing the filter as follows:
FILTER IS_DATESTRING(w.dateDue)
FILTER DATE_COMPARE(DATE_NOW(), w.dateDue, "years", "days")

Related

Filtering a list of values by a field value in GraphQL

So I'm doing some tests with GraphQL, and I'm failing in doing something that I believe is fairly simple.
When going to the GraphQL demo site (https://graphql.org/swapi-graphql) I'm presented with a default query which goes like this:
{
allFilms {
films {
title,
director,
releaseDate
}
}
}
This works as expected and returns a list of films.
Now - I would like to modify this query to return only the films where the director is George Lucas, and for the life of me - I can't figure out how to do that.
I've tried using the where and filter expressions, and also change the second line to films: (director: "George Lucas") but keep getting error messages.
What's the correct syntax for doing that?
Thanks!
If you check the docs of the provided GraphQL schema, you'll see that this is not possible. Following is the definition of the allFilms field:
allFilms(
after: String
first: Int
before: String
last: Int
): FilmsConnection
As per the doc, it has 4 input arguments, which are after, first, before, and last. There is no way to filter this out using the director's name.
GraphQL is not SQL. You cannot use expressions like WHERE or FILTER in GraphQL. The schema is already defined and the filters are pre-defined too. If the schema does not allow you to filter values using a certain field, you just can't do it.
You can to see the graphql schema here https://github.com/graphql/swapi-graphql/blob/master/schema.graphql
The allFilms query does not contain a filter for the field director. Also i can't find other query with this filter.
Most likely you need to write a filter on the result of the query.

How to return a query from cosmos db order by date string?

I have a cosmos db collection. I need to query all documents and return them in order of creation date. Creation date is a defined field but for historical reason it is in string format as MM/dd/yyyy. For example: 02/09/2019. If I just order by this string, the result is chaos.
I am using linq lambda to write my query in webapi. I have tried to parse the string and try to convert the string. Both returned "method not supported".
Here is my query:
var query = Client.CreateDocumentQuery<MyModel>(CollectionLink)
.Where(f => f.ModelType == typeof(MyModel).Name.ToLower() && f.Language == getMyModelsRequestModel.Language )
.OrderByDescending(f => f.CreationDate)
.AsDocumentQuery();
Appreciate for any advice. Thanks. It will be huge effort to go back and modify the format of the field (which affects many other things). I wish to avoid it if possible.
Chen Wang.Since the order by does not support derived values or sub query(link),so you need to sort the derived values by yourself i think.
You could construct the MM/dd/yyyy to yyyymmdd by UDF in cosmos db.
udf:
function getValue(datetime){
return datetime.substring(6,10)+datetime.substring(0,2)+datetime.substring(3,5);
}
sql:
SELECT udf.getValue(c.time) as time from c
Then you could sort the array by property value of class in c# code.Please follow this case:How to sort an array containing class objects by a property value of a class instance?

Elasticsearch custom scoring function test null date values

I can't find anywhere examples of how to test null values in ES custom scoring functions.
According to the doc the scripts are in groovy, according to the log the script is evaluated in painless, but even with that I'm left puzzled by some errors
"script":"doc['response_rate'].value ? (doc['response_rate'].value + 1) : 0",
"lang":"painless",
"caused_by":{
"type":"wrong_method_type_exception",
"reason":"cannot convert MethodHandle(Doubles)double to (Object)boolean"}}}]
This seems to say I'm trying to cas a double to boolean and raises, but I need to test for non-null values.
How should I write my scoring script ?
EDIT : I have understood that in painless I cannot use the ternary ? : operator, so I must write explicitely doc['xx'].value != null. However, this seems to produce weird results for dates that were indexed with null values. It would seem that in painless the value is NOT null (although it is indeed null in the json when I GET /_search it) and the following does not work
"script":"(doc['unavailable_until'].value != null) ? 1 : 0"
and always seem to return 0 (as if the null date was actually not null). I have seen some people reporting something some weird default date, in this case how can I compare this date to something like Date.now ?
I wonder why I couldn't find this page before...
Basically, one can just call .empty to check for null values. Works with dates too
"script":"doc['unavailable_until'].empty ? 1 : 0",

Check for null value in LINQ before performing operation on it

I am using the SharePoint 2010 REST services to extract information from an SP list. One of the conditions is that if a date exists in a record, and the year of that date is this year, then include it. Otherwise, don't.
What I'm concerned about is that I have to use a date cast method on the date field, and if that field is null then the code will fail. Is there any way to check if the value is null BEFORE using the cast?
My current code is here:
Dim results As List(Of CurrentProjectsItem) =
(From items In service.CurrentProjects
Where (items.StatusValue = "Closed" Or CDate(items.DateClosed).Year = Now.Year))
Order By items.Priority
Select items).ToList()
Any help would be appreciated, I don't use LINQ all that often!
You can include that check in your condition. So this:
CDate(items.DateClosed).Year = Now.Year
logically becomes this:
((items.DateClosed Is Not Nothing) And (CDate(items.DateClosed).Year = Now.Year))
(Though I'm curious what type DateClosed is in the first place, if not a Date?)
Edit:
The DateClosed is Date?
In that case it's a Nullable(Of Date) object, which has properties on it for checking this:
((items.DateClosed.HasValue) And (items.DateClosed.Value.Year = Now.Year))
No need for casting.

Couchdb view filtering by date

I have a simple document named Order structure with the fields id, name,
userId and timeScheduled.
What I would like to do is create a view where I can find the
document.id for those who's userId is some value and timeScheduledis
after a given date.
My view:
"by_users_after_time": {
"map": "function(doc) { if (doc.userId && doc.timeScheduled) {
emit([doc.timeScheduled, doc.userId], doc._id); }}"
}
If I do
localhost:5984/orders/_design/Order/_view/by_users_after_time?startKey="[2012-01-01T11:40:52.280Z,f98ba9a518650a6c15c566fc6f00c157]"
I get every result back. Is there a way to access key[1] to do an if
doc.userId == key[1] or something along those lines and simply emit on the
time?
This would be the SQL equivalent of
select id from Order where userId =
"f98ba9a518650a6c15c566fc6f00c157" and timeScheduled >
2012-01-01T11:40:52.280Z;
I did quite a few Google searches but I can't seem to find a good tutorial
on working with multiple keys. It's also possible that my approach is
entirely flawed so any guidance would be appreciated.
You only need to reverse the key, because username is known:
function (doc) {
if (doc.userId && doc.timeScheduled) {
emit([doc.userId, doc.timeScheduled], 1);
}
}
Then query with:
?startkey=["f98ba9a518650a6c15c566fc6f00c157","2012-01-01T11:40:52.280Z"]
NOTES:
the query parameter is startkey, not startKey;
the value of startkey is an array, not a string. Then the double quotes go around the username and date values, not around the array.
I emit 1 as value, instead of doc._id, to save disk-space. Every row of the result has an id field with the doc._id, then there's no need to repeat it.
don't forget to set an endkey=["f98ba9a518650a6c15c566fc6f00c157",{}], otherwise you get the data of all users > "f98ba9a518650a6c15c566fc6f00c157"
The answer actually came from the couchdb mailing list:
Essentially, the Date.parse() doesn't like the +0000 on the timestamps. By
doing a substring and removing the +0000, everything worked.
For the record,
document.write(new Date("2012-02-13T16:18:19.565+0000")); //Outputs Invalid
Date
document.write(Date.parse("2012-02-13T16:18:19.565+0000")); //Outputs NaN
But if you remove the +0000, both lines of code work perfectly.

Resources