Neo4j索引大量节点

时间:2014-11-18 00:41:31

标签: neo4j cypher

我正在学习neo4j的基础知识,我正在查看以下带有信用卡欺诈的示例https://linkurio.us/stolen-credit-cards-and-fraud-detection-with-neo4j。 Cypher查询找到所有被盗用户购物的商店

MATCH (victim:person)-[r:HAS_BOUGHT_AT]->(merchant)
WHERE r.status = “Disputed”
MATCH victim-[t:HAS_BOUGHT_AT]->(othermerchants)
WHERE t.status = “Undisputed” AND t.time < r.time
WITH victim, othermerchants, t ORDER BY t.time DESC
RETURN DISTINCT othermerchants.name as suspicious_store, count(DISTINCT t) as count, collect(DISTINCT victim.name) as victims
ORDER BY count DESC

但是,当用户数量增加时(比如数百万用户),此查询可能会变慢,因为初始查询必须遍历标记为person的所有节点。是否可以通过将属性设置为节点而不是事务来加速查询?我试图从关系中删除“status”属性并将其添加到节点(用户,而不是商家)。但是,当我使用约束WHERE victim.status="Disputed"运行查询时,查询不会返回任何内容。所以,在我的情况下,人有一个额外的财产'状态'。我认为我做了很多错事,但会很感激评论。例如

 MATCH (victim:person)-[r:HAS_BOUGHT_AT]->(merchant)
 WHERE victim.status = “Disputed”

返回正确数量的争议交易。同样适用于单独查询无争议交易的数量。但是,合并后,它们会产生一个空集。

如果我在方法中犯了错误,我怎样才能加快对大量节点的查询速度(避免在第一步中遍历所有节点)。我将使用具有类似属性的数据集,但将拥有大约1亿用户,因此我想在其他属性上为用户编制索引。

1 个答案:

答案 0 :(得分:1)

[被修改]

status属性从关系移动到person节点似乎不是正确的方法,因为我认为同一个人可以是多个商家的客户。

相反,您可以将关系重新定义为节点(让它标记为purchase),如:

(:person)-[:HAS_PURCHASE]->(:purchase)-[:BOUGHT_AT]->(merchant)

purchase个节点可以具有status属性。你只需要创建索引:

CREATE INDEX ON :purchase(status)

此外,您可以将time属性放在新的purchase节点中。

通过上述操作,您的查询将变为:

MATCH (victim:person)-[:HAS_PURCHASE]->(pd:purchase)-[:BOUGHT_AT]->(merchant)
WHERE pd.status = “Disputed”
MATCH victim-[:HAS_PURCHASE]->(pu:purchase)-[:BOUGHT_AT]->(othermerchants)
WHERE pu.status = “Undisputed” AND pu.time < pd.time
WITH victim, othermerchants, pu ORDER BY pu.time DESC
RETURN DISTINCT othermerchants.name as suspicious_store, count(DISTINCT pu) as count, collect(DISTINCT victim.name) as victims
ORDER BY count DES