python - py2neo 的 WriteBatch 操作失败

标签 python neo4j py2neo

我正在尝试找到解决以下问题的方法。我已经在这个 SO question 中看到它的准描述,但还没有真正回答。

以下代码失败,从一个新图开始:

from py2neo import neo4j

def add_test_nodes():
    # Add a test node manually
    alice = g.get_or_create_indexed_node("Users", "user_id", 12345, {"user_id":12345})

def do_batch(graph):
    # Begin batch write transaction
    batch = neo4j.WriteBatch(graph)

    # get some updated node properties to add
    new_node_data = {"user_id":12345, "name": "Alice"}

    # batch requests
    a = batch.get_or_create_in_index(neo4j.Node, "Users", "user_id", 12345, {})
    batch.set_properties(a, new_node_data)  #<-- I'm the problem

    # execute batch requests and clear
    batch.run()
    batch.clear()

if __name__ == '__main__':
    # Initialize Graph DB service and create a Users node index
    g = neo4j.GraphDatabaseService()
    users_idx = g.get_or_create_index(neo4j.Node, "Users")

    # run the test functions
    add_test_nodes()
    alice = g.get_or_create_indexed_node("Users", "user_id", 12345)
    print alice

    do_batch(g)

    # get alice back and assert additional properties were added
    alice = g.get_or_create_indexed_node("Users", "user_id", 12345)
    assert "name" in alice

简而言之,我希望在一个批处理事务中更新现有的 inode 属性。失败发生在 batch.set_properties 行,这是因为上一行返回的 BatchRequest 对象未被解释为有效节点。虽然不完全相同,但感觉我正在尝试类似于发布 here 的答案。

一些细节

>>> import py2neo
>>> py2neo.__version__
'1.6.0'
>>> g = py2neo.neo4j.GraphDatabaseService()
>>> g.neo4j_version
(2, 0, 0, u'M06') 

更新

如果我将问题分成不同的批处理,那么它可以无错误地运行:

def do_batch(graph):
    # Begin batch write transaction
    batch = neo4j.WriteBatch(graph)

    # get some updated node properties to add
    new_node_data = {"user_id":12345, "name": "Alice"}

    # batch request 1
    batch.get_or_create_in_index(neo4j.Node, "Users", "user_id", 12345, {})

    # execute batch request and clear
    alice = batch.submit()
    batch.clear()

    # batch request 2
    batch.set_properties(a, new_node_data)

    # execute batch request and clear
    batch.run()
    batch.clear()

这也适用于许多节点。虽然我不喜欢将批处理分开的想法,但这可能是目前唯一的方法。有人对此有何评论?

最佳答案

在阅读了 Neo4j 2.0.0-M06 的所有新功能后,节点和关系索引的旧工作流程似乎正在被取代。目前,neo 在建立索引的方式上存在一些分歧。即 labelsschema indexes .

标签

标签可以任意附加到节点上,并可以作为索引的引用。

索引

可以通过引用标签(此处为 User)和节点属性键(screen_name)在 Cypher 中创建索引:

CREATE INDEX ON :User(screen_name)

密码 MERGE

此外,索引get_or_create 方法现在可以通过新的密码MERGE 实现。函数,它非常简洁地包含标签及其索引:

MERGE (me:User{screen_name:"SunPowered"}) RETURN me

批量

通过将 CypherQuery 实例附加到批处理对象,可以在 py2neo 中对此类查询进行批处理:

from py2neo import neo4j

graph_db = neo4j.GraphDatabaseService()
cypher_merge_user = neo4j.CypherQuery(graph_db, 
    "MERGE (user:User {screen_name:{name}}) RETURN user")

def get_or_create_user(screen_name):
    """Return the user if exists, create one if not"""
    return cypher_merge_user.execute_one(name=screen_name)

def get_or_create_users(screen_names):
    """Apply the get or create user cypher query to many usernames in a 
    batch transaction"""
    
    batch = neo4j.WriteBatch(graph_db)
    
    for screen_name in screen_names:
        batch.append_cypher(cypher_merge_user, params=dict(name=screen_name))

    return batch.submit()

root = get_or_create_user("Root")
users = get_or_create_users(["alice", "bob", "charlie"])

限制

但是,有一个限制,即批量交易中密码查询的结果不能在同一交易中稍后引用。最初的问题是关于在一个批处理事务中更新一组索引用户属性。据我所知,这仍然是不可能的。例如,以下代码片段会引发错误:

batch = neo4j.WriteBatch(graph_db)
b1 = batch.append_cypher(cypher_merge_user, params=dict(name="Alice"))
batch.set_properties(b1, dict(last_name="Smith")})
resp = batch.submit()

因此,尽管使用 py2neo 在标记节点上实现 get_or_create 的开销似乎有所减少,因为不再需要遗留索引,但原始索引问题仍然需要 2 个单独的批处理交易才能完成。

关于python - py2neo 的 WriteBatch 操作失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20010509/

相关文章:

python - 默认为 python 类方法中的类变量?

csv - neo4j 全新安装无法识别 'using',导入时为 'load'

java - 如何连接 - 断开连接 - 重新连接到 Neo4j 服务器实例

python-3.x - py2neo v3 属性错误 : object has no attribute 'db_exists'

python - __next__ 和 __str__ 是否由等效的 next 和 str 函数在内部调用?

python - 我认为它不会花费那么多时间(for-if条件检查循环),有更好的方法吗?

python - 如何在 Pandas 的数据框子集中获得最大值?

neo4j - 如何在 Neo4J 2.0 Cypher 中获取附加到给定标签的所有索引

python - 我可以使用临时/替代的 neo4j 图表进行测试吗?

neo4j - 从列表中批量写入 py2neo