方案如下:
x
类型的节点,这些节点链接到y
类型的节点。x
节点之外的所有y
个节点,这些节点的属性等于特定值。示例输入:
CREATE (a:x {name: 'a'}), (b:x {name: 'b'}), (c:x {name: 'c'});
CREATE (d:y {name: 'd', attrib: 1}), (e:y {name: 'e', attrib: 2}),
(f:y {name: 'f', attrib: 3}), (g:y {name: 'g', attrib: 4}),
(h:y {name: 'h', attrib: 5}), (i:y {name: 'i', attrib: 6});
MATCH (a), (d), (e) WHERE a.name = 'a' AND d.name = 'd' AND e.name = 'e'
CREATE (a)-[r:z]->(d), (a)-[s:z]->(e) RETURN *;
MATCH (b), (f), (g) WHERE b.name = 'b' AND f.name = 'f' AND g.name = 'g'
CREATE (b)-[r:z]->(f), (b)-[s:z]->(g) RETURN *;
MATCH (c), (h), (i) WHERE c.name = 'c' AND h.name = 'h' AND i.name = 'i'
CREATE (c)-[r:z]->(h), (c)-[s:z]->(i) RETURN *;
在这里,我想返回所有x
个节点,但链接到y
节点attrib = 5
的节点除外。
这是我试过的:
MATCH (n:x)-[]-(m:y) WHERE NOT m.attrib = 5 RETURN n
通过此查询,我获得了所有x
个节点,即:a
,b
和c
。我想排除c
,因为它与h
相关联,后者有h.attrib = 5
。
修改
我找到了一个完成这项工作的查询:
MATCH (n:x), (m:x)-[]-(o:y)
WHERE o.attrib = 5
WITH collect(n) as all_x_nodes, collect(m) as bad_x_nodes
RETURN [n IN all_x_nodes WHERE NOT n IN bad_x_nodes]
问题在于效率不高。还有更好的选择吗?
答案 0 :(得分:0)
更好的方法是查找要排除的所有:x个节点(连接到具有特定属性的:y节点),收集这些x节点,然后匹配所有:x节点,这些节点不是在集合中:
MATCH (exclude:x)--(:y{attrib:5})
WITH collect(distinct exclude) as excluded
MATCH (n:x)
WHERE NOT n in excluded
RETURN collect(n) as result
使用APOC Procedures的另一种方法是获取两个集合,并从另一个集合中减去排除的集合:
MATCH (exclude:x)--(:y{attrib:5})
WITH collect(distinct exclude) as excluded
MATCH (n:x)
WITH excluded, collect(n) as nodes
RETURN apoc.coll.subtract(nodes, excluded) as result
在任何一种情况下,都有一个索引:y(attrib)。在这个数据集中,它并不重要。它将在更大的集合上。
答案 1 :(得分:0)
这个简单的查询应该完全符合您的要求:“返回除x
节点之外的所有y
节点,而attrib = 5
节点具有MATCH (n:x)
WHERE NOT (n)--(:y {attrib: 5})
RETURN n;
。”
>>> ft = 1 ^ a ^ 0 ^ b
>>> list(ft.satisfy_all())
[{a: 0, b: 0}, {a: 1, b: 1}]