2014-04-10 66 views
1

有沒有什麼辦法可以像下面那樣在一個模式中強制實現電子郵件地址的唯一性?Neo4j中數組的唯一性約束

(正:人{ID:{值},名稱:{值},電子郵件:[{值}]})

的想法是,沒有兩個人可以共享相同的電子郵件地址,但每個人可能有幾個電子郵件地址。所以,每個電子郵件地址在整個數據庫中應該只存在一次。

有一種明顯的骯髒的方法來做到這一點,即通過使每個電子郵件地址成爲節點並強制實現電子郵件節點以及電子郵件人員關係的唯一性,但這大大增加了節點的數量和查詢的複雜性在我的數據庫...

我想知道是否有更好的方法來執行這個約束,我不知道。

+1

好問題。我很確定答案是否定的,但希望別人會跳進來證明我錯了。只是爲了咯咯地笑,我嘗試了使用DISTINCT(這是這樣做的),但它不是一個函數,例如:create(n {vals:distinct(['foo','foo','bar'])}); - 沒有骰子。 – FrobberOfBits

回答

1

更新:這不起作用!請參閱下面的評論。

所以,我剛剛找到了解決方法。這不是一個完美的解決方案,但它適用於我的目的,而傳統索引仍然存在。希望在基於模式的索引獲取遺留Lucene索引的全部功能(包括使用Levenshtein距離的正則表達式和模糊搜索)之前,它們不會被刪除。

所以,我用下面的技巧來更新我的節點冗餘的email條目的情況下:

START n = node:node_auto_index(email={email_value}) 
MERGE (p:Person {id:n.id}) 
ON MATCH SET p.other_array_property = 
      p.other_array_property + {other_property_value} 
ON CREATE SET p.other_array_property = {other_property_value}; 

在這裏,我已經啓用的「電子郵件」屬性,這是一個數組屬性的傳統自動索引(如如上圖所示

現在,這並沒有爲節點創建建立一個約束,但它應該是我的目的(我正在整合來自不同來源的數據島)。可能還不夠...

希望有人會告訴我們更好的解決方案...

+0

lucene甚至不推薦模糊搜索,因爲它太昂貴了。他們通常建議自動完成,而不是(基於鍵入的字符,然後精確搜索) –

+0

哦,順便說一句。這不起作用,你必須這樣做:'START n = node:node_auto_index({email_query})'或確切地說:'node_auto_index(email = {email_value})' –

+0

感謝指出,我修復了腳本。 這裏我不需要模糊搜索,我只需要集合中每個成員的完整匹配。我在我的應用程序中使用模糊搜索(Leveneshtein距離),但這是爲了另一個目的。我使用它來比較數據庫中文件的simhashesh以查找類似的文件。這不能被自動補全替代,並且我的最佳知識是檢測類似文檔的最有效方法之一,如果我們不想走下去的話...... – retrography