【发布时间】:2016-09-18 11:17:01
【问题描述】:
给定模型
有一个模型,其中包含类别和它们之间的关系。 对于关系,可以指定它们是否绑定到特定的开始或结束类别。
有四种类型的关系:
- 仅指定开始类别(例如:“传出”)
- 仅指定结束类别(例如:“传入”)
- 指定了开始和结束类别(例如:“传出和传入”)
- 既未指定开始类别也未指定结束类别(例如:“未绑定”)
代码:
MERGE (cat:ModelCategory {title:'Cat'})
MERGE (rel1:ModelRelation {title:'Outgoing'})
MERGE (rel2:ModelRelation {title:'Incoming'})
MERGE (rel3:ModelRelation {title:'Outgoing and Incoming'})
MERGE (rel4:ModelRelation {title:'Unbound'})
MERGE (rel1)-[:STARTS_AT]->(cat)
MERGE (rel2)-[:ENDS_AT]->(cat)
MERGE (rel3)-[:STARTS_AT]->(cat)
MERGE (rel3)-[:ENDS_AT]->(cat)
单个查询
如果您选择“Cat”作为起始节点并想知道可以创建哪些关系和结果结束节点,您可以使用单个查询:
// Relations with current source and a target
// Returns relation "Outgoing and Incoming"
MATCH (relation:ModelRelation)-[STARTS_AT]->(:ModelCategory{title:"Cat"}),
(relation)-[ENDS_AT]->(target)
RETURN DISTINCT relation, target
// Relations with current source and without target
// Returns relation "Outgoing"
MATCH (relation:ModelRelation)-[STARTS_AT]->(:ModelCategory{title:"Cat"})
WHERE NOT (relation)-[:ENDS_AT]->()
MATCH (allCategories:ModelCategory)
RETURN relation, allCategories as target
// Relations with target, without source
// Returns relation "Incoming"
MATCH (relation:ModelRelation)-[ENDS_AT]->(target)
WHERE NOT (relation)-[:STARTS_AT]->()
RETURN relation, target
// Relations without source or target
// Returns relation "Unbound"
MATCH (relation:ModelRelation)
WHERE NOT (relation)-[:STARTS_AT]->() AND NOT (relation)-[:ENDS_AT]->()
MATCH (allCategories:ModelCategory)
RETURN relation, allCategories as target
问题
组合这四个查询的最佳方式是什么?
最简单的解决方案是在语句之间添加 UNION。
也许最好先获取标签 ModelRelation 和 ModelCategory 的所有节点并在子图上执行进一步的查询?
更新
更好的解决方案是区分有无指定目标的关系。 (导致一个类别或所有类别。)一个 UNION 仍然是必需的,并且两个子查询的第一部分是相同的。
// Relations which start at selected category or have no specified start
MATCH (relation:ModelRelation)
WHERE (relation)-[:STARTS_AT]->(:ModelCategory{title:"Cat"}) OR
NOT (relation)-[:STARTS_AT]->()
// Relations with specified targets
Match (relation)-[ENDS_AT]->(target)
RETURN relation, target
UNION
// Relations which start at selected category or have no specified start
MATCH (relation:ModelRelation)
WHERE (relation)-[:STARTS_AT]->(:ModelCategory{title:"Cat"}) OR
NOT (relation)-[:STARTS_AT]->()
// Relations without specified targets
MATCH (relation)
WHERE NOT (relation)-[:ENDS_AT]->()
MATCH (allCategories:ModelCategory)
RETURN relation, allCategories as target
【问题讨论】: