2017-01-29 26 views
0

我試圖改進商業網站的欺詐檢測系統。我們處理直接銀行交易,所以欺詐是我們需要管理的風險。我最近了解了圖形數據庫,並可以看到它如何應用於這些問題。因此,在過去的幾天裏,我設置了neo4j並解析了我們的數據:exampleneo4j欺詐檢測 - 高效的數據結構

我的直覺是爲每個訂單創建一個節點,併爲每個關聯的數據創建一個節點,然後連接他們都在一起。就像這樣:

MATCH (w:Wallet),(i:Ip),(e:Email),(o:Order) 
WHERE w.wallet="ex" AND i.ip="ex" AND e.email="ex" AND o.refcode="ex" 
CREATE (w)-[:USED]->(o),(i)-[:USED]->(o),(e)-[:USED]->(o) 

但此查詢運行速度非常慢作爲數據庫大小的增加(我假設,因爲它需要尋找我所要求的節點整個數據集)。運行如下查詢也需要很長時間:

START a=node(179) 
MATCH (a)-[:USED*]-(d) 
WHERE EXISTS(d.refcode) 
RETURN distinct d 

這是爲了提取連接到起點的所有訂單。我對Cypher很陌生(< 24小時),我發現搜索解決方案特別困難。

我可以解決哪些數據結構或查詢有任何具體問題以提高性能?理想情況下,需要在幾秒鐘內完成這種事情,就像我期望從SQL數據庫中獲得的那樣。目前我們有大約17,000個節點。

回答

0

總是一個好主意,通過完全讀取developers manual

爲了加速按屬性查找節點,您肯定需要創建indexes or unique constraints(取決於該屬性是否應該對標籤/值唯一)。

一旦您創建了所需的索引和約束條件,它們將在您的查詢的引擎下使用,以加快匹配速度。

START僅用於傳統索引,而對於最新的Neo4j版本,您應該使用MATCH來代替。如果您基於內部ID匹配,則可以使用MATCH (n) WHERE id(n) = xxx

請記住,您不應該在將來的查詢中保留用於查找的Neo4j之外的節點ID,因爲在節點被刪除和創建時可以重複使用內部節點ID,所以曾經引用了被刪除的節點的ID後來最終指向一個完全不同的節點。

在查詢中使用標籤應該有助於您的表現。在您查詢命令的查詢中,Neo4j必須檢查路徑中的每個末端節點,以查看屬性是否存在。屬性訪問通常很昂貴,尤其是當您使用可變長度匹配時,所以最好通過標籤來限制所需的節點。

MATCH (a)-[:USED*]-(d:Order) 
WHERE id(a) = 179 
RETURN distinct d 

在大圖表,可變長度的比賽可能會開始放緩,所以你可以通過安裝APOC Procedures並使用Path Expander過程來收集所有子節點和篩選下來只是爲了節點得到更多的表現。

MATCH (a) 
WHERE id(a) = 179 
CALL apoc.path.expandConfig(a, {bfs:true, uniqueness:"NODE_GLOBAL"}) YIELD path 
RETURN LAST(NODES(path)) as d 
WHERE d:Order