Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gremlin: Date filters

Filter Graph DB based on date field: I searched http://tinkerpop.apache.org/docs/current/reference/ but did not find a documentation for the same.

Did some research and it seems lt, gt, etc are working. BUT is my below approach the proper way? or is there a official way to do it? Below code works on Neptune and NEO4J but is this Vendor Independent.

Also found a 4/5 yr old post where it was recommended to use long, but I think its pretty old.


Sample data:

g.addV("TestDate2").property("title", "Alpha").property("date", "01-19-2018")
g.addV("TestDate2").property("title", "Bravo").property("date", "02-20-2018")
g.addV("TestDate2").property("title", "Charlie").property("date", "03-13-2018")
g.addV("TestDate2").property("title", "Delta").property("date", "04-14-2018")
g.addV("TestDate2").property("title", "Echo").property("date", "05-15-2018")
g.addV("TestDate2").property("title", "Foxtrot").property("date", "06-16-2018")
g.addV("TestDate2").property("title", "Hotel").property("date", "07-17-2018")
g.addV("TestDate2").property("title", "India").property("date", "08-18-2018")

Queries:

(I formatted the data of output so it wont really match Gremlin output buts its more readability)

Less than

g.V().has("TestDate2", "date", lt("03-03-2018")).valueMap()
{'date': ['02-20-2018'], 'title': ['Bravo']}
{'date': ['01-19-2018'], 'title': ['Alpha']}

g.V().has("TestDate2", "date", lt("03-24-2018")).valueMap()
{'date': ['03-13-2018'], 'title': ['Charlie']}
{'date': ['02-20-2018'], 'title': ['Bravo']}
{'date': ['01-19-2018'], 'title': ['Alpha']}

Greater than

g.V().has("TestDate2", "date", gt("06-16-2018")).valueMap()
{'date': ['07-17-2018'], 'title': ['Hotel']}
{'date': ['08-18-2018'], 'title': ['India']}

g.V().has("TestDate2", "date", gte("06-16-2018")).valueMap()
{'date': ['07-17-2018'], 'title': ['Hotel']}
{'date': ['06-16-2018'], 'title': ['Foxtrot']}
{'date': ['08-18-2018'], 'title': ['India']}

Between filter

g.V().has("TestDate2", "date", between("04-01-2018", "07-01-2018")).valueMap()
{'date': ['06-16-2018'], 'title': ['Foxtrot']}
{'date': ['04-14-2018'], 'title': ['Delta']}
{'date': ['05-15-2018'], 'title': ['Echo']}

Fails, but its fine

g.V().has("TestDate2", "date", lt("3-3-2018")).valueMap()
{'date': ['03-13-2018'], 'title': ['Charlie']}
{'date': ['07-17-2018'], 'title': ['Hotel']}
{'date': ['02-20-2018'], 'title': ['Bravo']}
{'date': ['06-16-2018'], 'title': ['Foxtrot']}
{'date': ['04-14-2018'], 'title': ['Delta']}
{'date': ['08-18-2018'], 'title': ['India']}
{'date': ['01-19-2018'], 'title': ['Alpha']}
{'date': ['05-15-2018'], 'title': ['Echo']}
like image 444
Srinath Ganesh Avatar asked Jul 06 '18 07:07

Srinath Ganesh


1 Answers

If you are submitting Gremlin query as a String from Python (or any other language for that matter), Amazon Neptune has a custom syntax for specifying dates. You can use the function datetime() to specify your date as a String in a ISO8061 format. This syntax identifies the String as a Date object and processes it accordingly. Hence, you do not have to rely on lexicographic String comparison for comparing Dates. This is documented here.

For example, you can write your queries as String as follows:

// Insert Date as property
String insertQuery = "g.addV('TestDate2').property('title','Alpha').property('date', datetime('2018-01-19T00:00:00'))";

// Query for the date added above
String query = "g.V().hasLabel('TestDate2').has('date',gte(datetime('1929-01-01T00:00:00'))).valueMap()";

Having said that, as others have mentioned, you can also use a GLV client (submit queries using Gremlin bytecode instead of String) and use the client language's native Date implementation itself.

like image 182
Divij Vaidya Avatar answered Oct 13 '22 01:10

Divij Vaidya