2016-08-01 34 views
3

我有一個GraphAware時間樹和空間r樹,用於引用圖中的一大組節點。我試圖按時間和空間搜索這些記錄。當我試圖篩選這些結果的性能急劇下降如何在Neo4j中有效地過濾多個過程調用的結果

WITH 
({start:1300542000000,end:1350543000000}) as tr 
CALL ga.timetree.events.range(tr) YIELD node as n 
RETURN count(n); 
> ~ 500000 results 

WITH 
({lon:120.0,lat:20.0}) as smin, ({lon:122.0,lat:21.0}) as smax 
CALL spatial.bbox('spatial_records', smin, smax) YIELD node as n 
RETURN count(n); 
> ~ 30000 results 

獨立,我可以收集這些查詢的結果在大約5秒鐘。 Neo4j已經在我的系統中佔用了大量的內存,所以我的印象是這個命令的內存佔用量在我的系統上過多,並且查詢永遠不會結束。 (我使用到的Neo4j-shell來運行這些命令)

WITH 
({start:1300542000000,end:1350543000000}) as tr, 
({lon:120.0,lat:20.0}) as smin, ({lon:122.0,lat:21.0}) as smax 

CALL ga.timetree.events.range(tr) YIELD node as n 
CALL spatial.bbox('spatial_records', smin, smax) YIELD node as m 

WITH COLLECT(n) as nn, COLLECT(m) as mm 

RETURN FILTER(x in nn WHERE X in mm); 

我想知道什麼是最好的方式,有效地過濾這兩種說法是調用的結果。我試圖使用REDUCE子句,但無法完全弄清楚語法。

作爲一個側面的問題,考慮到這是我將發佈到數據庫中的最常見的查詢類型,這是一種很好的方式來做事情(如使用時間樹和r樹引用相同的一組節點)?我還沒有在neo4j中找到任何其他支持在單一結構中索引空間和時間的工具,所以這是我目前的實現。

回答

2

第一個程序會返回500k個節點,而收集操作是一個代價高昂的操作,所以是的,這會讓內存變得非常沉重。

我會從什麼返回給你較少的節點,然後使用密碼而不是一個過程開始,所以在這裏我將用Cypher中的一個範圍查詢過濾器替換對timetree過程的調用。

假設你有一個索引timestamp財產您的節點上:

CALL spatial.bbox('spatial_records', smin, smax) YIELD node as m 
WITH m 
WHERE m.timestamp > 1300542000000 and m.timestamp < 1350543000000 
RETURN m 

我不會建議刪除timetree(否則我會被解僱< - 笑話)。在某些時間查詢的情況下,timetree將會勝過查詢範圍內的查詢,特別是當分辨率很高(毫秒)並且您有很多非常連續的時間戳時。

否則,你似乎有一個非常好的用例,如果你能發送更多關於neo4j懈怠或私人(christophe at graphaware dot com)的更多細節,這可能會幫助Neo4j和GraphAware支持更多的東西通過程序(比如傳遞一組節點並過濾掉那些不在範圍內或與空間平滑組合),只要它足夠通用即可。與此同時,由於您使用的是開源產品,因此您可以輕鬆創建一個爲您的特定用例組合兩個過程的過程。

+0

感謝您的回覆。我絕對考慮進入Java世界,看看我是否可以做出自己的調用,以某種方式在並行運行的結果上進行低成本的基於散列的連接。但說實話,我有點害怕,因爲我沒有太多的Java經驗。 我簡要地看了一下apoc庫,發現了一些有趣的調用。不確定那裏有什麼會有幫助。 – spanishgum