neo4j中基于时间/日期的搜索 [英] Time/date based searches in neo4j

查看:794
本文介绍了neo4j中基于时间/日期的搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在与neo4j玩耍时,出现了两个问题。目前有2种:




  • 在搜索从节点X到节点的特定路径时如何限制关系/边是(RegEx?/通配符?)?例如,所有边都具有2个时间属性,开始和结束。我想找到在凌晨2点到凌晨3点之间发生的节点之间的路径。?

  • 如何跟踪时间路径?假设有一辆汽车从 A驶向 B。该路线花费了一个小时,即从早上5点到早上6点。从 B到 C的下一个部分也花了一个小时,但是从早上7点到早上8点,因为驾驶员休息了一个小时。如何以仅允许逻辑上有效(时间)路径的方式查询neo4j。例如,这应该是有效的:



(布拉格)-[:DISTANCE {开始: 5 am ,end:'6 am'}]->(布尔诺),(Brno)-[:DISTANCE {开始:'7 am',end:'9 am'}]->(Liberec)



而这个无效:



(布拉格)-[ :DISTANCE {开始:'5 am',结束:'6 am'}]->(布尔诺),(布尔诺)-[:DISTANCE {开始:'4 am',结束:'6 am'}]-> ;(Liberec)



另一个示例,如下图所示:

  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))
创建((a)-[:FORWARDED {start_time:'11:00 am'}]->(d))
创建((d)-[:FORWARDED {start_time:'10:00 am'}]->(b))

我正在寻找从节点 A到节点 B的路径。忽略约束 start_time,此图中有3条可能的路径:




  • 'A'-> ; ‘B’

  • ‘A’-> ‘C’-> ‘B’

  • ‘A’-> ‘D’-> 'B'



在这种情况下,我们仅考虑约束 start_time,剩下两个路径: / p>


  • 'A'-> ‘B’

  • ‘A’-> ‘C’-> ‘B’



是因为路径‘A’-> ‘D’-> ‘B’无效。在这种情况下,时间顺序是错误的。 Cooworker'A'在上午11点将包裹发送给Cooworker'D',但一个小时前,cooworker将此特定包裹转发给了Cooworker'B'。巫婆是不可能的。



PS:有没有一种工具可以生成边缘为ASCII艺术的节点。对于控制台? :)

解决方案

首先,我建议您使用数字时间值而不是字符串。它将使Cypher变得更加简单和高效。同样,实际上,路径可能会跨越多天,因此仅提供一天中的某个时间会导致错误的结果。例如,您可能要使用时代时间。在我的答案中,我假设时间是数字。



此查询应仅返回有效的从A到B的路径:

  MATCH p =(a:BoxingMachine {title:'A'})-[:FORWARDED *]->(b:BoxingMachine {title:'B'} )
与p,RELENCESHIPS(p)会在
减少(s = true,i在范围内(1,SIZE(rels)-1)|
时(rels [i] ).start_time>(rels [i-1])。start_time
THEN s
ELSE false END)
RETURN p;

REDUCE 子句负责检查



您可以使用此数据检查结果(使用简单的数字时间值,但纪元时间也可以):

p>

 创建(a:BoxingMachine {title:'A'})
创建(b:BoxingMachine {title:'B' }}
创建(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))


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? :)

解决方案

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))

这篇关于neo4j中基于时间/日期的搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆