查询以返回已经匹配的节点集中没有特定关系的节点

时间:2016-10-07 16:47:46

标签: neo4j cypher

以下语句创建我尝试使用的数据:

CREATE (p:P2 {id: '1', name: 'Arthur'})<-[:EXPANDS {recorded: 1, date:1}]-(:P2Data {wage: 1000})
CREATE (d2:P2Data {wage: 1100})-[:EXPANDS {recorded: 2, date:4}]->(p)
CREATE (d3:P2Data {wage: 1150})-[:EXPANDS {recorded: 3, date:3}]->(p)
CREATE (d3)-[:CANCELS]->(d2)

所以,Arthur已经创建并且最初的工资为1000.在第2天,我们从第4天<添加 1100 的信息/ strong>以后。在第3天,我们声明工资将增加至 1150 取消从第2天开始的

现在,如果我查看历史记录,因为它在给定时间点有效,当时间点为2时,以下历史记录是正确的:

  • 第1天 - 工资1000
  • 第4天 - 工资1100

当时间点为3时,以下历史记录是正确的:

  • 第1天 - 工资1000
  • 第3天 - 工资1150

以图形术语表示,当我根据:EXPANDS关系匹配P2Data时,我需要那些没有被匹配的其他P2Data节点取消的那些。

这是我到目前为止的尝试:

MATCH p=(:P2 {id: '1'})<-[x1:EXPANDS]-(d1:P2Data)
WHERE x1.recorded <= 3
WITH x1.date as date, 
FILTER(n in nodes(p) 
  WHERE n:P2Data AND 
  SIZE(FILTER(n2 IN nodes(p) WHERE (n2:P2Data)-[:CANCELS]->(n))) = 0) AS result
RETURN date, result

我们的想法是只通过n in nodes(p)关系获取那些没有路径指向它的:CANCELS

由于我还是新手,并且某些cypher还没有为我点击过,所以请完全放弃该查询。

2 个答案:

答案 0 :(得分:1)

MATCH (:P2 {id: '1'})<-[x1:EXPANDS]-(d1:P2Data)
WHERE x1.recorded <= 3
WITH x1.date AS valid_date, x1.recorded AS transaction_date, d1.wage AS wage
ORDER BY valid_date
WITH COLLECT({v: valid_date, t: transaction_date, w:wage}) AS dates
WITH REDUCE(x = [HEAD(dates)], date IN TAIL(dates)|
    CASE
    WHEN date.v = LAST(x).v AND date.t > LAST(x).t THEN x[..-1] + [date]
    WHEN date.t > LAST(x).t THEN x + [date]
    ELSE x 
    END) AS results
UNWIND results AS result
RETURN result.v, result.w

我试图想出一种更好地塑造这种模式的方法,但老实说我很难过。

答案 1 :(得分:1)

如果您通过删除canceled关系来修改数据模型,而是将EXPANDS日期添加到CREATE (p:P2 {id: '1', name: 'Arthur'})<-[:EXPANDS {recorded: 1, date:1}]-(:P2Data {wage: 1000}) CREATE (d2:P2Data {wage: 1100})-[:EXPANDS {recorded: 2, date:4, canceled: 3}]->(p) CREATE (d3:P2Data {wage: 1150})-[:EXPANDS {recorded: 3, date:3}]->(p) 关系类型,则可以大大简化所需的查询。

例如,创建测试数据:

MATCH p=(:P2 {id: '1'})<-[x1:EXPANDS]-(d1:P2Data)
WHERE x1.recorded <= 3 AND (x1.canceled IS NULL OR x1.canceled > 3)
RETURN x1.date AS date, d1
ORDER BY date;

执行简单查询:

#top-navigation {
	float: left;
	padding-top: 4px;
}

#top-navigation ul {
	list-style: none;
	position: relative;
}

#top-navigation ul a {
	display: block;
	color: #ffffff;
	text-decoration: none;
}

#top-navigation ul a:hover {
	color: #f68364;
}

#top-navigation ul li {
	position: relative;
	float: left;
	margin: 0px 10px;
}

#top-navigation ul li:hover {
	color: #f68364;
}

#top-navigation ul ul:before {
	content: '';
	display: block;
	margin: auto;
	width: 0;
	height: 0;
	background: transparent !important;
	border-left: 10px solid transparent;
	border-right: 10px solid transparent;
	border-bottom: 10px solid #6d5d68;
}

#top-navigation ul ul {
	display: none;
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: 150px;
	background: #f68364;
}

#top-navigation ul ul li {
	float: none;
	margin: 0px;
}

#top-navigation ul ul a {
	display: block;
	padding: 10px;
}

#top-navigation ul ul a:hover {
	background: #6d5d68;
	color: #ffffff;
}

#top-navigation ul ul ul {
	top: 0;
	left: 100%;
}

#top-navigation ul li:hover > ul {
	display: block;
}