【问题标题】:Unique constraints on node properties after the fact事后对节点属性的唯一约束
【发布时间】:2015-11-12 21:04:46
【问题描述】:

我有一个测试版网站,其中包含名为主题的节点。我忘记将唯一约束添加到 name 属性,现在有重复的节点。我使用 MERGE 希望它能找到唯一的名称并添加关系,但显然情况并非如此。无论如何将所有关系合并到单个节点,然后删除重复项,以便在清理约束后添加约束?

我找到了这个,但我有多个具有不同关系的节点。有人知道如何修改它以适应我的情况吗?

//编辑

使用 Michael 的代码,我将块修改为:

MATCH (t:Topic)
WITH t.name as name, collect(t) as topics, count(*) as cnt
WHERE cnt > 1
WITH head(topics) as first, tail(topics) as rest
LIMIT 1000
UNWIND rest AS to_delete
OPTIONAL MATCH (to_delete)-[r:TOPIC_OF]->(g:Group)
FOREACH (x in case when r is null then [] else [1] |
   MERGE (first)-[new_r:TOPIC_OF]->(g)
   // in case you have to copy-rel-properties
   SET new_r = r
   DELETE r
)
OPTIONAL MATCH (to_delete)<-[r2:INTEREST_OF]-(p:Person)
FOREACH (x in case when r2 is null then [] else [1] |
   MERGE (first)-[new_r2:INTEREST_OF]->(p)
   // in case you have to copy-rel-properties
   SET new_r2 = r2
   DELETE r2
)

OPTIONAL MATCH (to_delete)<-[r3:SKILL_OF]-(p:Person)
FOREACH (x in case when r3 is null then [] else [1] |
   MERGE (first)-[new_r3:SKILL_OF]->(p)
   // in case you have to copy-rel-properties
   SET new_r3 = r3
   DELETE r3
)

OPTIONAL MATCH (to_delete)-[r4:TOPIC]->(p:Project)
FOREACH (x in case when r4 is null then [] else [1] |
   MERGE (first)-[new_r4:TOPIC]->(p)
   // in case you have to copy-rel-properties
   SET new_r4 = r4
   DELETE r4
)

OPTIONAL MATCH (to_delete)-[r5:NEEDS]->(p:Project)
FOREACH (x in case when r5 is null then [] else [1] |
   MERGE (first)-[new_r5:NEEDS]->(p)
   // in case you have to copy-rel-properties
   SET new_r5 = r5
   DELETE r5
)
DELETE to_delete
RETURN count(*);

运行时出现错误:

Invalid input '|': expected whitespace, comment, '.', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR or END (line 8, column 52 (offset: 276))
"FOREACH (x in case when r is null then [] else [1] |"

我错过了什么?

【问题讨论】:

  • 你在使用 neoxygen/neoclient 吗?
  • 是的,我正在使用 Neoclient

标签: php neo4j cypher


【解决方案1】:

你可以稍微修改一下来处理更多的rels:

MATCH (t:Topic)
WITH t.name as name, collect(t) as topics, count(*) as cnt
WHERE cnt > 1
WITH head(topics) as first, tail(topics) as rest
LIMIT 1000
UNWIND rest AS to_delete
OPTIONAL MATCH (to_delete)-[r:TOPIC_OF]->(g:Group)
FOREACH (x in case when r is null then [] else [1] |
   MERGE (first)-[new_r:TOPIC_OF]->(g)
   // in case you have to copy-rel-properties
   SET new_r = r
   DELETE r
)
OPTIONAL MATCH (to_delete)-[r2:TOPIC_OF2]->(g:Group)
FOREACH (x in case when r is null then [] else [1] |
   MERGE (first)-[new_r2:TOPIC_OF2]->(g)
   // in case you have to copy-rel-properties
   SET new_r2 = r2
   DELETE r2
)
DELETE to_delete
RETURN count(*);

【讨论】:

  • 我编辑了我最初的问题以包含您的代码块并进行了一些修改,但我不确定我做对了,我收到了一个错误
【解决方案2】:

我遇到了类似的问题(我认为)- 请参阅 my question here。虽然我的问题没有得到解答,但我提出的技术和查询确实解决了我的问题。这有帮助吗?

我使用的查询类似于

// get all outgoing relationships
MATCH (a:Label1 { title : 'blah' })-[r]->(o)
RETURN r
// returns FOO and BAR

// for each relationship type, create one from (d) and copy the properties over
MATCH (a:Label1 { title : 'blah' })-[r:FOO]->(o), (d:Label1 { title : 'blah blah' })
CREATE (d)-[r2:FOO]->(o)
SET r2 = r
...etc...

// now do the same for incoming relationships
MATCH (a:Label1 { title : 'blah' })<-[r]-(o)
RETURN r
// returns FOO and BAR

// for each relationship type, create one from (d) and copy the properties over
MATCH (a:Label1 { title : 'blah' })<-[r:FOO]-(o), (d:Label1 { title : 'blah blah' })
CREATE (d)<-[r2:FOO]-(o)
SET r2 = r
...etc...

// finally delete node and relationships (if required)
MATCH (a:Label1 { title : 'blah' })-[r]-(o)
DELETE r, a

当然,这只有在您可以分别识别由 a 和 d 标识的节点时才会有所帮助...

【讨论】:

    猜你喜欢
    • 2015-08-04
    • 2020-10-25
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多