neo4j - Neo4j APOC 分配的RelationshipProperties,removedRelationshipProperties 触发器和apoc.index.in
问题描述
我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
关系的所有键的添加/更新/删除感兴趣。
解决方案
这assignedRelationshipProperties
是相当棘手的。这个参数的结构是Map<String, List<Map<String, Object>>>
。
其中,第一个String
是属性的键,列表元素是具有以下键的映射:
- key : 属性的键
- old:旧值(如果有)
- new :分配给属性的新值
- 关系:有问题的关系
为了更直观,这是参数在调试格式中的样子:
对于您的特定用例,更新特定关系类型的关系属性更新的 lucene 索引,您可以使用以下查询:
CALL apoc.trigger.add('test-rel-trigger',
'UNWIND keys({assignedRelationshipProperties}) AS key
UNWIND {assignedRelationshipProperties}[key] AS map
WITH map WHERE type(map.relationship) = "HAS_VALUE_ON"
CALL apoc.index.addRelationship(map.relationship, keys(map.relationship)) RETURN count(*)'
, {phase:'before'})
至于删除,因为您索引了完整的属性图,我相信您可以替换assignedRelationshipProperties
为removedRelationshipProperties
推荐阅读
- swift - NSPopover 以分离状态启动
- spring - 使用 Spring 制作一个简单的发票 web 应用程序,但哪些技术是可取的?
- sql-server - 在 T-SQL 中连接多个表并缺少一个表的空行
- vba - 是否可以创建 VBA 宏来编辑同一工作簿中的另一个宏?
- typescript - 通过 TypeScript 列表中的另一个元素获取项目
- laravel - 共享主机上的 Laravel 邮件
- c - scanf() 在多行输入中暂停循环
- sql - 如何将此 SELECT 语句转换为 DELETE?
- c# - 从烘焙机的开始日期计算非固定天数循环
- python-sphinx - 在 Sphinx 重组文本中隐藏标题级别