Sun*_*red 9 python neo4j py2neo
我试图找到解决以下问题的方法.我已经看到它在这个SO问题中准备描述,但没有真正回答.
以下代码失败,从新图开始:
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
简而言之,我希望在一个批处理事务中更新现有的索引节点属性.失败发生在该batch.set_properties行,这是因为BatchRequest前一行返回的对象未被解释为有效节点.虽然不是完全同意,但感觉我正在尝试类似于此处发布的答案
一些细节
>>> 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目前存在一些分歧.即标签和模式索引.
标签可以任意附加到节点,并可以作为索引的参考.
可以通过引用标签(此处User)和节点属性键(screen_name)来在Cypher中创建索引:
CREATE INDEX ON :User(screen_name)
MERGE此外,索引get_or_create方法现在可以通过新的cypher MERGE函数实现,该函数非常简洁地包含了标签及其索引:
MERGE (me:User{screen_name:"SunPowered"}) RETURN me
可以py2neo通过将CypherQuery实例附加到批处理对象来批处理查询:
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()
因此,似乎虽然get_or_create使用py2neo旧标记不再需要使用标记节点实现标记节点的开销较少,但原始问题仍需要完成2个单独的批处理事务.