neo4j用于欺诈检测 - 高效的数据结构

时间:2017-01-29 15:22:50

标签: neo4j

我正在努力改进商业网站的欺诈检测系统。我们处理直接银行交易,因此欺诈是我们需要管理的风险。我最近了解了图形数据库,并可以看到它如何应用于这些问题。所以,在过去的几天里,我设置了neo4j并将数据解析为:example

我的直觉是为每个订单创建一个节点,为每个订单创建一个节点,然后将它们连接在一起。像这样:

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个节点。

1 个答案:

答案 0 :(得分: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