Neo4j Cypher模式理解与可选匹配

时间:2017-10-13 09:00:30

标签: neo4j cypher

我有以下模式理解:

[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) 
| {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria

现在我需要为此查询添加其他可选匹配..类似这样的内容:

[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) 
   OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(v1:Vote)-[:VOTED_ON]->(c1) 
| {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria

但它不适用于Cypher错误 - org.neo4j.driver.v1.exceptions.ClientException: Invalid input 'P': expected 'r/R'

请说明如何正确添加此可选匹配。

已更新

我需要这样的东西:

[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD)<-[:VOTED_FOR*0..1]-(v1:Vote)-[:VOTED_ON]->(c1) 
| {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes), userVotes: v1} ] AS weightedCriteria

换句话说,我需要将v1的列表作为weightedCriteria.userVotes(SDN @QueryResult)的子列表,但是现在我的测试在这个新查询中失败了 - 它预计3条记录,但返回13 ...

这是一个Neo4j沙箱:

https://10-0-1-12-35256.neo4jsandbox.com/browser/

用户名:neo4j 密码:probe-jumps-lick

这是我的旧查询:

MATCH (parentD)-[:CONTAINS]->(childD:Decision) 
WHERE parentD.id = 1 
WITH childD , parentD  
ORDER BY childD.createDate DESC 
SKIP 0 LIMIT 100 
WITH * 
MATCH (childD)-[ru:CREATED_BY]->(u:User) 
OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User)  
RETURN ru, u, rup, up, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: toInt(entity.id),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) 
    | {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD)  WHERE  NOT ((ch1)<-[:DEPENDS_ON]-())  
    | {characteristicId: toInt(ch1.id),  value: v1.value, available: v1.available, totalHistoryValues: v1.totalHistoryValues, totalFlags: v1.totalFlags, description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

这是一个新的Cypher查询:

MATCH (parentD)-[:CONTAINS]->(childD:Decision) 
WHERE parentD.id = 1 
WITH childD , parentD  
ORDER BY childD.createDate DESC 
SKIP 0 LIMIT 100 
WITH * 
MATCH (childD)-[ru:CREATED_BY]->(u:User) 
OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User)  
RETURN ru, u, rup, up, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: toInt(entity.id),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD)<-[:VOTED_FOR*0..1]-(v1:Vote)-[:VOTED_ON]->(c1) 
    | {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes), userVotes: v1} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD)  WHERE  NOT ((ch1)<-[:DEPENDS_ON]-())  
    | {characteristicId: toInt(ch1.id),  value: v1.value, available: v1.available, totalHistoryValues: v1.totalHistoryValues, totalFlags: v1.totalFlags, description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

我相信这个查询工作正常,并在Criteria和Votes之间产生JOIN ..这就是为什么我从上一个查询中看到13条记录而不是3条...

如果您可以向我展示如何返回3行(使用根级别的Criterion信息和投票的嵌套信息(子列表)而不是13个不同的记录,那将是非常好的...

我需要的解决方案将生成3个原始记录(作为第一个查询),带有嵌套信息而不是JOINS ...我需要这个,因为我将查询结果的自定义投影到我的对象模型中,需要有一个Votes的子列表作为weightedCriteria的属性。

同样在这种模式理解中,我必须按用户过滤投票 - 类似这样:(v1)-[ru:CREATED_BY]->(u:User) WHERE u.id = {userId}

是否可以实施?

1 个答案:

答案 0 :(得分:2)

您可以使用OPTIONAL MATCH关系中的variable-length pattern matching代替:VOTED_FOR而不是OPTIONAL MATCH。从0到1的可变长度将等同于[ (parentD)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD)<-[:VOTED_FOR*0..1]-(v1:Vote)-[:VOTED_ON]->(c1) | {criterionId: toInt(c1.id), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria

[:VOTED_FOR*0..1]

void libFoo() { // does some stuff printf("boring message"); // does some more stuff } 使这种关系在模式中是可选的。