【问题标题】:Are my Cypher statements 'overdone'我的 Cypher 陈述是否“过度”
【发布时间】:2015-06-18 18:39:03
【问题描述】:

我正在使用 py2neo 进行交易。这意味着我正在使用 Cypher 语言。我将文本 Cypher 语句追加到事务队列,并通过 commit 一次性提交队列的内容。

它工作正常。但是,它很慢。我每秒获得大约 100 个/节点,并且随着事务队列变大,插入需要更长的时间。如果交易有超过 6,000 个节点(以及类似数量的关系),我的应用程序就会超时。

现在我想专注于我的 Cypher。我的应用会生成很多这样的内容:

CREATE (n:METHOD {version: 6995, unique: 682, return_type: 0, fully_qualified_name: 0, name: "method4", accessibility: 0})
CREATE (n:PARAMETER {version: 6995, unique: 687, fully_qualified_name: 0, param_type: 1, name: "param4", accessibility: 0})
MATCH (a:METHOD), (b:PARAMETER) WHERE a.unique=682 AND a.version=6995 AND b.unique=687 AND b.version=6995 CREATE (a)-[r:INVOKED_WITH]->(b)

所以我创建一个 METHOD 节点,创建一个 PARAMETER 节点,然后将它们关联起来。困扰我的是我基本上创建了两个节点,然后抛弃了我刚刚创建它们的事实。然后我通过查找找到它们,以便我可以连接它们。这让我很恼火。以前的版本没有使用事务;当我创建一个节点时,我得到了一个原生的 neo4j ID,并在创建关系时使用了它。现在我不能这样做,因为文本语句正在大量提交到 neo4j 服务器。

我是否可以像在 neo4j 网络界面中那样将 RETURN 语句放入其中?有没有更好的 Cypher 可以使用?

EDIT - 我对所有相关节点类型的“唯一”属性都有索引。

我没有在我的 Python 代码中使用参数,因为代码正在使用事务。因此我必须使用 py2neo 的机制直接与 neo4j 对话。这涉及创建您在上面看到的文本命令。

【问题讨论】:

  • 100 个节点/秒看起来很慢,即使是通过一个看似不必要的 MATCH,但它应该工作得很好。我确实喜欢大约 50 毫秒内的 1200 条语句,所以...现在,您对匹配的所有属性都有索引或约束吗?你在你的python代码中使用参数吗?可以发一下吗?
  • @ChristopheWillemsen 我更新了我的问题。查看底部的修改。
  • 我不明白您对事务的评论,我可以将 python 与事务一起使用并使用参数。没有参数,执行计划不能被缓存,所以..
  • @ChristopheWillemsen 我们正在使用 py2neo。根据我阅读的内容,它不直接支持事务。

标签: neo4j py2neo


【解决方案1】:

Py2neo 支持事务,当然您可以在密码查询中使用参数,这是我刚刚测试的一个简单代码:

from py2neo import Graph
import time

graph = Graph("http://neo4j:password@localhost:7474/db/data/");

tx = graph.cypher.begin()
for x in range(0,100):
    tx.append("CREATE (m:Method {id:{id}})", {"id": x})
    tx.append("CREATE (p:Parameter {id:{id}})", {"id": x})
    tx.append("MATCH (m:Method {id:{mid}}), (p:Parameter {id: {pid}}) CREATE (m)-[:RELATES]->(p)", {"mid": x, "pid": x})

mstart = int(round(time.time() * 1000))
tx.commit()
mend = int(round(time.time() * 1000))
diff = mend - mstart
print diff

diff时间在80ms左右

更新,你也可以这样做:

    tx.append("CREATE (m:Method {id:{method_id}}) WITH m
               UNWIND {parameter_ids} as p_id 
               CREATE (p:Parameter {id:p_id})
               CREATE (m)-[:RELATES]->(p)", 
              {"method_id": 1234, "parameter_ids":range(0,100)})

【讨论】:

  • 技术上,py2neo 不支持事务。这就是为什么您不能在其中使用本机 py2neo 对象的原因。 py2neo 的好心人向我们公开了 Cypher 接口。现在我了解该参数属性的用途!在我更改代码时...
  • 您的建议使代码明显更快。我还没有完全实现,所以不知道最终的结果……但是初步的结果非常令人满意。
  • 酷,还要注意 CREATE 不会处理可能存在的具有相同 id 的节点,或者节点之间的现有关系,所以也许你会想看看 MERGE 子句
  • 幸运的是,这是一个加载器。不会有更新,所有节点都有唯一的 ID。我现在已经完成了所有的更改,现在我的节点数为 2200+(有关系)/秒
  • 你也可以使用tx.append("CREATE (m:Method {data})", {"data":{"id": x,"prop":"value"}})
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 2012-03-08
  • 2012-08-11
  • 2021-12-14
  • 1970-01-01
相关资源
最近更新 更多