我正在努力改进商业网站的欺诈检测系统 . 我们处理直接银行交易,因此欺诈是我们需要管理的风险 . 我最近了解了图形数据库,并可以看到它如何应用于这些问题 . 所以,在过去的几天里,我设置了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 回答
始终是一个好主意,完全阅读developers manual .
为了加速属性对节点的查找,您肯定需要创建indexes or unique constraints(取决于属性是否应对标签/值唯一) .
一旦您创建了所需的索引和约束,它们将在您的查询中用于加速您的匹配 .
START仅用于旧版索引,对于最新的Neo4j版本,您应该使用MATCH . 如果您根据内部ID进行匹配,则可以使用
MATCH (n) WHERE id(n) = xxx
.请记住,您不应该在Neo4j之外保留节点ID以便在将来的查询中进行查找,因为内部节点ID可以在删除和创建节点时重复使用,因此曾经引用已被删除的节点的ID可能稍后会指向到一个完全不同的节点 .
在查询中使用标签可以帮助您提高性能 . 在您查找订单的查询中,Neo4j必须检查路径中的每个终端节点以查看该属性是否存在 . 属性访问往往很昂贵,尤其是当您使用可变长度匹配时,因此最好通过标签限制所需的节点 .
在较大的图形上,可变长度匹配可能开始减慢,因此您可以通过安装APOC Procedures并使用Path Expander过程来收集所有子图节点并过滤到只有Order节点来获得更高的性能 .