2015-11-04 108 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"