考虑Neo4J 2.0 Cypher查询
MERGE (u:User {id_str:"123"})
ON CREATE SET
u.name="Bob",
ON MATCH SET
u.phone_num="555-4152"
RETURN u
这是一个愚蠢的问题 - 不要担心这里的意图。问题是,我如何理解这个查询是创建还是只是找到一个节点?
更新
也许我应该进一步激励我为什么要这种行为。原因如下:如果节点已经存在,那么就不必转到远程服务器(在我的情况下是Twitter API)并下载所有用户的元数据。如果ON CREATE可以某种方式链接回一个回调来拉下这些数据,那将是很好的。这种行为似乎不太可能在Cypher中实现。所以我可能要做的就是做一个匹配,如果get返回NULL,那么我将调用Twitter API,获取元数据并进行创建。
答案 0 :(得分:4)
我认为这与MERGE
的意图相反。您可以使用它来描述执行查询后图形的外观,而不是在读取之前查找它的外观 - 读取和写入操作应该在Cypher中严格分开。也就是说,您可以设置像@LameCoder这样的虚拟属性:
MERGE (u:User {id_str:"123"})
ON CREATE SET u.onCreate = true
WITH u, has(u.onCreate) as onCreate
REMOVE n.onCreate
RETURN u, u.onCreate
如果创建,将返回(u), true
,如果没有,则返回(u), false
,并且不会产生任何副作用。或者您可以维护时间戳,可能是一个用于创建节点,一个用于节点上次修改时 - 我认为这是文档中的一个示例。此
MERGE (u:User {id_str:"123"})
ON CREATE SET u.created = timestamp()
ON MATCH SET u.lastModified = timestamp()
RETURN u, has(u.lastModified) as onMerge
与上面的查询类似。
答案 1 :(得分:0)
在Neo4j控制台中,您可能会看到查询返回了 summary 和 response 。在Python中,我检查了result.summary().counters.nodes_created != 0
。
示例:使用创建时间戳创建连接节点
query = """
match (root:User {username:$root})
merge (root) -[:HAS_ROOM]-> (r:Room {id:$rid})
on create set r.timestamp = timestamp()
return r"""
result = session.run(query, root=user, rid=role)
count = result.summary().counters.nodes_created
record = result.single() # Node data
if count > 0: print(f"Node {record['rp']} created")
else: print(f"Using an existing node {record['rp']}")