【问题标题】:Neo4j Cypher pattern comprehension with optional matchNeo4j Cypher 模式理解与可选匹配
【发布时间】:2017-10-13 09:00:29
【问题描述】:

我有以下模式理解:

[ (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 行(根级别的标准信息和投票的嵌套信息(子列表))而不是 13 个不同的记录,那将是非常棒的...

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

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

可以实现吗?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    您可以在:VOTED_FOR 关系中使用variable-length pattern matching 来代替OPTIONAL MATCH。从零到一的可变长度将等效于OPTIONAL MATCH

    [ (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] 使这个关系在模式中是可选的。

    【讨论】:

    • 感谢您的回答!查询工作没有错误,但我的测试因断言而失败 - 在旧查询上我有 3 条记录 - 在你的 - 13 条记录...但我希望有相同的 3 条记录作为 weightedCriteria 并返回 v1:Vote 作为子列表对于每个加权标准
    • 好的,创建了 Neo4j 沙箱,请查看我更新的问题
    • 嗨@Bruno Peres,你有如何实现这个的想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    相关资源
    最近更新 更多