Time/date based searches in neo4j

99封情书 提交于 2019-12-23 01:27:09

问题


while playing around with neo4j a couple of questions arisen. At present time there are 2 of them:

  • How can I limit the relationships/edges while searching for a specific path from node X to node Y (RegEx?/Wildcard?)? For instance all edges have 2 time attributes, "begin" and "end". I would like to find a path between nodes which occured between 2 am and 3 am in the morning.?
  • How can track a time path? Lets say a car drove from 'A' to 'B'. The route took one hour, namely from 5 am to 6 am. The next section, from 'B' to 'C' took as well one hour but from 7 am to 8 am because the driver took a one hour rest. How can I query neo4j in the way that only logically valid (time) paths are allowed. For instance this should be valid:

(Prague) -[:DISTANCE {begin: '5 am', end: '6 am'}]->(Brno), (Brno) -[:DISTANCE {begin: '7 am', end: '9 am'}]->(Liberec)

whereas this one shall be invalid:

(Prague) -[:DISTANCE {begin: '5 am', end: '6 am'}]->(Brno), (Brno) -[:DISTANCE {begin: '4 am', end: '6 am'}]->(Liberec)

Another example, given is the following graph:

CREATE (a:BoxingMachine {title: 'A'})
CREATE (b:BoxingMachine {title: 'B'})
CREATE (c:BoxingMachine {title: 'C'})
CREATE (d:BoxingMachine {title: 'D'})
CREATE ((a)-[:FORWARDED {start_time:  '9:00 am'}]->(b))
CREATE ((a)-[:FORWARDED {start_time:  '7:00 am'}]->(c))
CREATE ((c)-[:FORWARDED {start_time:  '8:00 am'}]->(b))
CREATE ((a)-[:FORWARDED {start_time: '11:00 am'}]->(d))
CREATE ((d)-[:FORWARDED {start_time: '10:00 am'}]->(b))

I am looking for paths from node 'A' to node 'B'. Ignoring the constraint "start_time", we have 3 possible paths in this graph:

  • 'A' --> 'B'
  • 'A' --> 'C' --> 'B'
  • 'A' --> 'D' --> 'B'

In the case we consider the constraint "start_time" only, two paths left:

  • 'A' --> 'B'
  • 'A' --> 'C' --> 'B'

because the path 'A' --> 'D' --> 'B' is invalid. In this case the chronology is wrong. Cooworker 'A' send a package to cooworker 'D' at 11am but cooworker forwarded this particular package to cooworker 'B' a hour earlier. Witch is impossible.

PS: Is there a tool to generate the nodes with there edges as ASCII art resp. for the console? :)


回答1:


First, I would advise that you use a numeric time value instead of a string. It would make the Cypher a lot simpler and efficient. Also, practically speaking, paths can span multiple days, so just providing a time of day will lead to wrong results. For instance, you may want to use epoch time. In my answer, I assume that the times are numeric.

This query should only return paths from A to B that are valid:

MATCH p=(a:BoxingMachine{title: 'A'})-[:FORWARDED*]->(b:BoxingMachine{title: 'B'})
WITH p, RELATIONSHIPS(p) AS rels
WHERE REDUCE(s = true, i IN RANGE(1, SIZE(rels)-1) |
  CASE WHEN (rels[i]).start_time > (rels[i-1]).start_time
  THEN s
  ELSE false END)
RETURN p;

The REDUCE clause is responsible for checking that the start times in a candidate path make sense.

You can check the results using this data (with simple numeric time values, but epoch time would also work):

CREATE (a:BoxingMachine {title: 'A'}) 
CREATE (b:BoxingMachine {title: 'B'}) 
CREATE (c:BoxingMachine {title: 'C'}) 
CREATE (d:BoxingMachine {title: 'D'}) 
CREATE ((a)-[:FORWARDED {start_time:  9}]->(b)) 
CREATE ((a)-[:FORWARDED {start_time:  7}]->(c)) 
CREATE ((c)-[:FORWARDED {start_time:  8}]->(b)) 
CREATE ((a)-[:FORWARDED {start_time: 11}]->(d)) 
CREATE ((d)-[:FORWARDED {start_time: 10}]->(b))


来源:https://stackoverflow.com/questions/36789608/time-date-based-searches-in-neo4j

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