我們有一個Neo4J數據庫,代表一個具有大約100K節點和200K關係的演化過程。節點代代相傳,邊代表親子關係。主要目標是能夠在最後一代中獲得一個或多個感興趣的節點,並探索它們的進化歷史(粗略地說,「我們是如何到達這裏的?」)。尋求Neo4J Cypher查詢很長(但幾乎)唯一的路徑
的「明顯的」第一次查詢找到自己的所有祖先不工作,因爲有通過空間太多的可能祖先和路徑:
match (a)-[:PARENT_OF*]->(c {is_interesting: true})
return distinct a;
因此,我們已經預先處理過的數據,以便某些邊被標記爲「特殊」,使得每個節點至多具有一個「特殊」父邊,儘管偶爾兩個父邊都被標記爲「特殊」。我希望,那麼,是這條查詢(有效)生成一起「特殊」的邊緣(幾乎)獨特的道路:
match (a)-[r:PARENT_OF* {special: true}]->(c {is_interesting: true})
return distinct a;
然而,這仍然是unworkably緩慢。
這很令人沮喪,因爲「作爲一個人」,其邏輯很簡單:從少量的「有趣」節點開始(通常爲1,最多不超過幾十個),並沿着幾乎總是唯一的「特殊「的邊緣。假設具有兩個「特殊」父節點的節點數量非常少,這應該是類似於O(N)的東西,其中N是時間回退的代數。
在Neo4j的,但是,可以追溯到從那裏每步驟是唯一一個獨特的「有趣」的節點25步,但需要30秒,而一旦有一個單分叉(其中父母雙方均爲「特殊」 )作爲步驟的函數,它會變得更糟。 28步(使我們到達第一個分岔點)需要2分鐘,30分鐘(仍然只有一個分岔點)需要6分鐘,而我甚至沒有想過在模擬開始時嘗試完整的100步。
去年的一些類似工作似乎表現更好,但我們使用了各種邊緣標籤(例如,(a)-[:SPECIAL_PARENT_OF*]->(c)
以及(a)-[:PARENT_OF*]->(c)
),而不是在邊緣使用數據字段。查詢關係字段值不是一個好主意嗎?我們在這個模型(一些布爾值,一些數字)中關聯了不同的值,並且我們希望/假設我們可以使用這些值來有效地限制搜索,但也許情況並非如此。
有關如何調整我們的模型或查詢的建議將不勝感激。
更新我應該提到,這是所有與Neo4J 2.1.7。按照布萊恩安德伍德的建議,我會給2.2一個嘗試,並會報告回來。
我真的很想親自看到這個答案。我肯定有一些開放式路徑長度的Cypher查詢,看起來他們不應該穿越很多,但需要一段時間。 – 2015-04-06 07:24:27