How to handle dates in neo4j

荒凉一梦 提交于 2019-11-30 07:25:44

问题


I'm an historian of medieval history and I'm trying to code networks between kings, dukes, popes etc. over a period of time of about 50 years (from 1220 to 1270) in medieval Germany. As I'm not a specialist for graph-databases I'm looking for a possibility to handle dates and date-ranges.

Are there any possibilities to handle over a date-range to an edge so that the edges, which represents a relationship, disappears after e.g. 3 years?

Are there any possibility to ask for relationships who have their date-tag in a date-range?


回答1:


The common way to deal with dates in Neo4j is storing them either as a string representation or as millis since epoch (aka msec passed since Jan 01 1970).

The first approach makes the graph more easily readable the latter allows you to do math e.g. calculate deltas.

In your case I'd store two properties called validFrom and validTo on the relationships. You queries need to make sure you're looking for the correct time interval.

E.g. to find the king(s) in charge of France from Jan 01 1220 to Dec 31st 1221 you do:

MATCH (c:Country{name:'France'})-[r:HAS_KING]->(king)
WHERE r.validFrom >= -23667123600000 and r.validTo <=-23604051600000
RETURN king, r.validFrom, r.validTo

addendum

Since Neo4j 3.0 there's the APOC library which provides couple of functions for converting timestamps to/from human readable date strings.




回答2:


You can also store the dates in their number representation in the following format: YYYYMMDD

In your case 12200101 would be Jan 1st 1220 and 12701231 would be Dec 31st 1270.

It's a useful and readable format and you can perform range searches like:

MATCH (h:HistoricEvent)
WHERE h.date >= 12200101 AND h.date < 12701231
RETURN h

It would also let you order by dates, if you need to.




回答3:


As of Neo4J 3.4, the system handles duration and dates, see the official documentation. See more examples here.

An example related to the original question: Retrieve the historical events that happened in the last 30 days from now :

WITH duration({days: 30}) AS duration
MATCH (h:HistoricEvent)
WHERE date() - duration < date(h.date)
RETURN h



回答4:


Another option for dates that keeps the number of nodes/properties you create fairly low is a linked list years (earliest year of interest - latest year), one of months (1-12), and one of dates in a month (1-31). Then every "event" in your graph can be connected to a year, month, and day. This way you don't have to create a new node for every new combination of a year month and day. You just have a single set of months, one of days, and one year. I scale the numbers to make manipulating them easier like so

Years are yyyy*10000

Months are mm*100

Date are dd

so if you run a query such as

match (event)-[:happened]->(t:time) 
with event,sum(t.num) as date 
return event.name,date
order by date

You will get a list of all events in chronological order with dates like Janurary 17th, 1904 appearing as 19040117 (yyyymmdd format)

Further, since these are linked lists where, for example, ...-(t0:time {num:19040000})-[:precedes]->(t1:time {num:19050000})-... ordering is built into the nodes too.

This is, so far, how I have liked to do my event dating



来源:https://stackoverflow.com/questions/29343767/how-to-handle-dates-in-neo4j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!