我将Neo4j 3.3.5 Community Edition
与APOC 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
关系的所有密钥的添加/更新/删除感兴趣。
答案 0 :(得分:1)
有使用这些函数的专用辅助函数,这些函数在docs中用于访问node / rels或这些数据结构的属性:
请参阅:https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_triggers
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}]