2013-08-17 64 views
1

从Neo4j 1.9.2开始,并使用Cypher查询语言,我想创建具有特定属性值的节点之间的关系。 我有一组具有属性H的节点G,G节点之间当前没有任何关系。使用一个Cypher查询创建具有相同属性值的节点之间的关系

在Cypher语句中,是否有可能通过H属性值对G节点进行分组,并在每个节点之间创建一个关系HR以成为同一组?知道每个组的大小在2 & 10之间,并且对于大约50k G节点,我有超过15k个这样的组(15k个不同的H值)。

我试过很难管理这样的查询,却没有找到正确的语法。下面是一个小样本数据集:

create 
(G1 {name:'G1', H:'1'}), 
(G2 {name:'G2', H:'1'}), 
(G3 {name:'G3', H:'1'}), 

(G4 {name:'G4', H:'2'}), 
(G5 {name:'G5', H:'2'}), 
(G6 {name:'G6', H:'2'}), 
(G7 {name:'G7', H:'2'}) 
return * ; 

最后,我想这样的关系:

G1-[:HR]-G2-[:HR]-G3-[:HR]-G1 

和:

G4-[:HR]-G5-[:HR]-G6-[:HR]-G7-[:HR]-G4 

在另一种情况下,我可能需要更新大量使用/比较一些属性的节点之间的关系。假设类型为N的节点和类型为M的节点,N个节点与M有关,其关系名为:IS_LOCATED_ON。位置的顺序可以作为N个节点的属性来存储(N.relativePosition从1到MAX_POSITION长),但是我们可能稍后需要以这种方式更新图模型:使N个节点之间通过新的: PRECEDES关系,这样我们就可以在给定集合上找到更容易和更快的下一个节点N.

我希望这样的语言可以允许更新大量的节点/关系操纵其属性。

  • 难道不可能吗?
  • 如果不是,是否计划或可能计划?

任何帮助将不胜感激。

回答

2

由于没有什么你提供获得排名的数据,我已经收藏 发挥得到一个如下:

START 
    n=node(*), n2=node(*) 
WHERE 
    HAS(n.H) AND HAS(n2.H) AND n.H = n2.H 
WITH n, n2 ORDER BY n2.name 
WITH n, COLLECT(n2) as others 
WITH n, others, LENGTH(FILTER(x IN others : x.name < n.name)) as rank 
RETURN n.name, n.H, rank ORDER BY n.H, n.name; 

大厦关闭的那然后就可以开始确定关系的

START 
    n=node(*), n2=node(*) 
WHERE 
    HAS(n.H) AND HAS(n2.H) AND n.H = n2.H 
WITH n, n2 ORDER BY n2.name 
WITH n, COLLECT(n2) as others 
WITH n, others, LENGTH(FILTER(x IN others : x.name < n.name)) as rank 
WITH n, others, rank, COALESCE(
    HEAD(FILTER(x IN others : x.name > n.name)), 
    HEAD(others) 
    ) as next 
RETURN n.name, n.H, rank, next ORDER BY n.H, n.name; 

最后(稍微更稠)

START 
    n=node(*), n2=node(*) 
WHERE 
    HAS(n.H) AND HAS(n2.H) AND n.H = n2.H 
WITH n, n2 ORDER BY n2.name 
WITH n, COLLECT(n2) as others 
WITH n, others, COALESCE(
    HEAD(FILTER(x IN others : x.name > n.name)), 
    HEAD(others) 
    ) as next 
CREATE n-[:HR]->next 
RETURN n, next; 
+0

你好@LameCoder,谢谢你的回答。这个查询不是很直接,但我理解这个逻辑。 因为我不需要在节点上创建HR自我关系,所以我们可以添加另一个限制(g1 <> g2),它允许删除COALESCE语句,因为我们不需要按名称命令g2: (g1.H)和HAS(g2.H)AND g1.H = g2.H AND g1≠g2 WITH g1,COLLECT(*),g2 = node(*) WHERE g2)as other WITH g1,HEAD(others)as next CREATE g1 - [:HR] - > next RETURN g1,next; –

+0

(...继续...) 查询当前正在运行,但执行真的很长。您的查询运行时间超过8小时(30052902毫秒),并创建了47412个关系,因为我在数据集上除外。 看来,2节点START子句是一种糟糕的方法,即使我使用索引来查找g1和g2。 上述更新后的查询当前正在运行,如果它提高了性能,我会在稍后看到结果,但它在几个小时后运行,因此这种方法不是一个好的解决方案。使用Java代码花费几秒钟来加载数据并创建关系。 无论如何感谢您的提示@LameCoder。 ;) –

+0

@RaphaelF。这不是一个理想的解决方案。我只是想看看我们可以让Cypher做什么,这是一个非常有趣的谜题。像这样的问题让我希望有存储过程。 – LameCoder

0

你可以只是那样做,也许表明方向的关系:

CREATE 
    (G1 { name:'G1', H:'1' }), 
    (G2 { name:'G2', H:'1' }), 
    (G3 { name:'G3', H:'1' }), 
    (G4 { name:'G4', H:'2' }), 
    (G5 { name:'G5', H:'2' }), 
    (G6 { name:'G6', H:'2' }), 
    (G7 { name:'G7', H:'2' }), 
    G1-[:HR]->G2-[:HR]->G3-[:HR]->G1, 
    G4-[:HR]->G5-[:HR]->G6-[:HR]->G7-[:HR]->G1 

为例见http://console.neo4j.org/?id=ujns0x

+0

您好,叔他的问题是图形已经与所有节点一起创建。我不能硬编码每个45k节点的关系。我想稍后使用Cypher创建它们。我想我可以使用Java语言,但我在这里想知道Cypher的功能。 –

相关问题