2015-12-29 40 views
1

下一個Neo4j版本的功能請求:Neo4j已經支持以排序順序保存屬性的索引,從而實現快速查找。例如。一個人的名字,一個可能有一個看起來像指數:neo4j中高效的重複節點查找

愛麗絲 鮑勃 卡羅爾 戴夫 艾米莉 (....)

這樣一個可以查找「戴夫」與二進制搜索(O(log n))而不是線性掃描(O(n))。

但是,也可以使用索引來有效地查找重複項(某些屬性具有相同值的節點)。例如,如果想要列出每個「人」節點共享相同名字的一組列表,Neo4j 2.3似乎(通過Cypher中的EXPLAIN)執行的操作是將每個節點的名字與其他所有名字進行比較,是O(N^2)。例如。此查詢:

介紹匹配(一個:人)用一根火柴(B:人)WHERE a.name = b.name RETURN A,B LIMIT 5

示出了笛卡兒積步驟和隨後的過濾步驟。但隨着名字的指數,一個可以做線性掃描過類似的列表:

愛麗絲 愛麗絲 愛麗絲 鮑勃 卡羅爾 卡羅爾 戴夫 艾米莉 弗蘭克 弗蘭克 弗蘭克 (.... )

比較項目#1到#2,#2到#3等,以每次掃描O(n)時間構建所有重複項的有序列表。 Neo4j似乎不支持,但它會對我的應用程序非常有用,所以我想提出一個請求。

回答

0

我對你可能會嘗試的建議有幾點建議,但如果你發現它們不足(沒有其他人有更好的想法),我會建議將新功能建議提交給Neo4j GitHub issues list

所以我想知道如果Neo4j認爲屬性特殊。如果您在標籤/屬性(您可以使用CREATE INDEX ON :person(name)創建)上有索引,那麼比較屬性和字符串應該非常高效。我試圖通過名字通過只是一個變量,它似乎有較少的DB打在我小的考驗DB:

MATCH (a:person) 
WITH a, a.name AS name 
MATCH (b:person) 
WHERE name = b.name 
RETURN a, b LIMIT 5 

這似乎給我更少的DB命中,當我PROFILE它。

另一種解決方法是,由於您在談論同一組對象,因此按名稱對節點進行分組,然後爲每個組抽出對。像這樣:

MATCH (a:person) 
WITH a.name AS name, collect(a) AS people 
UNWIND people AS a 
UNWIND people AS b 
WITH name, a, b 
WHERE a <> b 
RETURN a, b LIMIT 50 

在這裏,我們收集了每個獨一無二的名稱的數組(我們也可以下/上,如果我們想成爲不區分大小寫),然後UNWIND兩次獲得陣列的笛卡爾積。由於我們正在逐組進行工作,因此這應比將每個節點與其他每個節點進行比較快得多。