我正在Neo4j数据库中使用这种查询:
MERGE(n:type {key:"xyz"})
ON CREATE SET n.create_date = timestamp()
ON MATCH SET n.update_date = timestamp()
SET n.att1=value1, n.att2=value2
ON MATCH将帮助我确定是否找到了节点,但不能确定属性是否已真正更改。
是否可以使用任何方法来检测节点的任何属性已更改?例如,再次运行相同的查询将更改update_date属性,而不会真正更改属性。我希望能够检测到att1或att2已更改。
非常感谢
答案 0 :(得分:4)
使用APOC触发器可以实现:
首先,下载并安装APOC并启用它:
apoc.trigger.enabled=true
dbms.security.procedures.unrestricted=apoc.trigger.*
dbms.security.procedures.whitelist=apoc.*
然后您可以添加一个触发器,该触发器将在attr1
属性更改时做出反应:
CALL apoc.trigger.add(
'updateTimestamp',
'UNWIND apoc.trigger.propertiesByKey({assignedNodeProperties},"attr1") as prop
WITH prop.old as oldProp, prop.new as newProp, prop.node AS n
SET n.updated_at = timestamp()', {phase:'before'});
测试:
CREATE (n:Node) SET n.attr1 = "hello"
MATCH (n:Node) RETURN n
╒════════════════════════════════════════════╕
│"n" │
╞════════════════════════════════════════════╡
│{"updated_at":1543313569105,"attr1":"hello"}│
└────────────────────────────────────────────┘
更新节点:
MATCH (n:Node) SET n.attr1 = "hellonew"
MATCH (n:Node) RETURN n
╒═══════════════════════════════════════════════╕
│"n" │
╞═══════════════════════════════════════════════╡
│{"updated_at":1543313626248,"attr1":"hellonew"}│
└───────────────────────────────────────────────┘
再次执行以检查是否在不更改属性的情况下未触发它:
MATCH (n:Node) SET n.attr1 = "hellonew"
MATCH (n:Node) RETURN n
╒═══════════════════════════════════════════════╕
│"n" │
╞═══════════════════════════════════════════════╡
│{"updated_at":1543313626248,"attr1":"hellonew"}│
└───────────────────────────────────────────────┘
答案 1 :(得分:1)
基于Christophe的出色支持,我对apoc进行了一些尝试,并使用此解决方案为所有以u_开头的属性创建了触发器。
CALL apoc.meta.data() YIELD label, property, elementType WHERE elementType = "node" AND property =~ "^u_.*" WITH DISTINCT property AS key
CALL apoc.trigger.add(
'trig_upd_'+key,
'UNWIND apoc.trigger.propertiesByKey({assignedNodeProperties},"'+key+'") as prop
WITH prop.old as oldProp, prop.new as newProp, prop.node AS n
SET n.last_updated = timestamp()', {phase:'before'})
YIELD name
RETURN name;
我将继续处理这一问题,现在的目标是找到一种在新建或删除属性的情况下创建或删除触发器的方法。
BR 雷米(Rémi)