Neo4j APOC assignedRelationshipProperties,removedRelationshipProperties触发器和apoc.index.in

时间:2018-05-09 12:59:46

标签: neo4j cypher neo4j-apoc

我将Neo4j 3.3.5 Community EditionAPOC apoc-3.3.0.2-all.jar

一起使用

我有触发器,允许我添加/删除特定关系中的所有属性到/从手动索引:

CALL apoc.trigger.add('HAS_VALUE_ON_CREATED_RELATIONSHIPS_TRIGGER',
'UNWIND {createdRelationships} AS r 
MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic) 
CALL apoc.index.addRelationship(r, keys(r)) RETURN count(*)', {phase:'after'})

CALL apoc.trigger.add('HAS_VALUE_ON_DELETED_RELATIONSHIPS_TRIGGER',
\"UNWIND {deletedRelationships} AS r 
MATCH (d:Decision)-[r:HAS_VALUE_ON]->(Characteristic) 
CALL apoc.index.removeRelationshipByName('HAS_VALUE_ON', r) RETURN count(*)\", {phase:'after'})

我的业务逻辑还可以引入新属性或从现有关系中删除现有属性,因此我认为为了使我的索引保持最新,我还应该使用另外两个语句,例如:

assignedRelationshipProperties
removedRelationshipProperties
我是对的吗?如果是这样,您能否说明如何使用它们来添加新的触发器并更新/删除MATCH (d:Decision)-[r:HAS_VALUE_ON]->(ch:Characteristic)关系中的索引属性?

更新#1

我已经在答案部分提供了经过验证的解决方案,但遗憾的是它并不起作用。请参阅以下详细信息:

我创建了以下触发器:

CALL apoc.trigger.add('TEST_TRIGGER', "UNWIND keys({assignedRelationshipProperties}) AS key 
UNWIND {assignedRelationshipProperties}[key] AS map 
WITH map 
WHERE type(map.relationship) = 'LIVES_IN' 
CALL apoc.index.addRelationship(map.relationship, keys(map.relationship)) 
RETURN count(*)", {phase:'before'})

验证CALL apoc.trigger.list()

存在触发器

创建以下节点和关系:

CREATE (p:Person) return p
CREATE (c:City) return c

MATCH (p:Person), (c:City) CREATE (p)-[r:LIVES_IN]->(c) RETURN type(r)

尝试通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

quthe ery返回空结果,现在很好。

指定关系新属性time,其值为10

MATCH (p:Person)-[r:LIVES_IN]->(c:City) SET r.time = 10 RETURN r

尝试通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

查询成功返回预期的Person节点

现在,我为time属性重新分配了另一个值= 11

MATCH (p:Person)-[r:LIVES_IN]->(c:City) SET r.time = 11 RETURN r

尝试再次通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City)
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:11') YIELD node AS person 
RETURN person

查询返回两者的空结果。

为什么在属性更改后索引未更新?

更新#2

我创建了以下触发器:

CALL apoc.trigger.add('HAS_VALUE_ON_ASSIGNED_RELATIONSHIP_PROPERTIES_TRIGGER',
"UNWIND apoc.trigger.propertiesByKey({assignedRelationshipProperties}, 'time') AS prop WITH prop.relationship as r 
CALL apoc.index.addRelationship(r, keys(r)) 
RETURN count(*)", {phase:'after'})

验证CALL apoc.trigger.list()

存在触发器

创建以下节点和关系:

CREATE (p:Person) return p
CREATE (c:City) return c

MATCH (p:Person), (c:City) CREATE (p)-[r:LIVES_IN]->(c) RETURN type(r)

尝试通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City)
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

查询返回空结果,现在没问题。

指定关系新属性time,其值为10

MATCH (p:Person)-[r:LIVES_IN]->(c:City) SET r.time = 10 RETURN r

尝试通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

查询成功返回预期的Person节点

现在,我为time属性重新分配了另一个值= 11

MATCH (p:Person)-[r:LIVES_IN]->(c:City) SET r.time = 11 RETURN r

尝试再次通过索引查询访问它:

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:10') YIELD node AS person 
RETURN person

MATCH (p:Person)-[r:LIVES_IN]->(c:City) 
CALL apoc.index.in(c, 'LIVES_IN', 'time:11') YIELD node AS person 
RETURN person

查询返回两者的空结果。

因此,这种方法遇到了与我之前描述的相同的问题。另一个缺点是我需要指定确切的密钥名称 - 在本例中为time。但我对某些密钥不感兴趣,而是对HAS_VALUE_ON关系的所有密钥的添加/更新/删除感兴趣。

1 个答案:

答案 0 :(得分:1)

有使用这些函数的专用辅助函数,这些函数在docs中用于访问node / rels或这些数据结构的属性:

请参阅:https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_triggers

表4.辅助函数

apoc.trigger.nodesByLabel({assignedLabels/assignedNodeProperties},'Label')

按标签过滤labelEntries的函数,用于在{assignedLabels}{removedLabels}的触发器语句中使用 {phase:'before/after/rollback'} 返回上一个和新的触发器信息

apoc.trigger.propertiesByKey({assignedNodeProperties},'key')

通过property-key过滤propertyEntries的函数,用于在{assignedNode/RelationshipProperties}{removedNode/RelationshipProperties}的触发器语句中使用。

返回[{old,[new],key,node,relationship}]