2015-11-04 69 views
2

我有我的节点属性A保存字符串值的数组删除重复:从节点阵列性能

n.A=["ABC","XYZ","123","ABC"]

合并过程中我经常会写类似n.A = n.A + "New Value"代码。我遇到的问题是我的数组中存在重复的值;不是无法克服的,但我想避免它。

  • 我该如何编写一个密码查询来删除数组A中的所有重复值?在这一点上已经插入了一些重复项,我想清理它们。
  • 当向现有数组添加新值时,我怎样才能确保只保存具有不同值的数组副本? (可能最终被确切相同的逻辑用于解决第一个问题)

回答

2

查询添加非重复的值,可以有效地进行(在这个例子中,我假设提供了idnewValue参数):

OPTIONAL MATCH (n {id: {id}}) 
WHERE NONE(x IN n.A WHERE x = {newValue}) 
SET n.A = n.A + {newValue}; 

此查询不创建一个临时数组,只会改变n.A数组如果它尚未包含{newValue}字符串。

将帖子

如果你想(一)创建n节点,如果它不存在,和(b)追加{newValue}n.A只有{newValue}是不是已经在n.A,这应该工作:

OPTIONAL MATCH (n { id: {id} }) 
FOREACH (x IN (
    CASE WHEN n IS NULL THEN [1] ELSE [] END) | 
    CREATE ({ id: {id}, A: [{newValue}]})) 
WITH n, CASE WHEN EXISTS(n.A) THEN n.A ELSE [] END AS nA 
WHERE NONE (x IN nA WHERE x = {newValue}) 
SET n.A = nA + {newValue}; 

如果OPTIONAL MATCH失败,那么FOREACH子句将创建一个新的节点的节点(与{id}和含有{newValue}数组),和下面的SET子句将做因为n将是NULL。

如果OPTIONAL MATCH成功,则FOREACH条款将不做任何事情,下面SET子句将追加到{newValue}当且仅当n.A该值尚不在n.A存在。如果应执行SET,但现有节点不具有n.A属性,则查询会将空数组连接到{newValue}(从而生成仅包含{newValue}的数组),并将其设置为n.A的值。

+0

我将如何将它合并到我的MERGE声明的ON MATCH部分?现在我有 MERGE(n {id:{id}}) ON CREATE SET n.A = [{newValue}] ON MATCH SET n.A = n。A + {newValue}' 在'ON MATCH'之后,我尝试了一些代码,但Neo4j告诉我唯一允许的项目是'SET'。 – Peter

+0

查看我答案的附录。 – cybersam

2

与其他故障排除结合的一些资料上UNWIND并与用于从现有阵列属性删除重复以下的Cypher查询上来。

match (n) 
unwind n.system as x 
with distinct x, n 
with collect(x) as set, n 
set n.system = set 
2

一旦你已经清理现有的重复,你可以添加新的值时,使用此:

match (n) 
set n.A = filter (x in n.A where x<>"newValue") + "newValue"