【问题标题】:Combine multiple relationship types and return data from both relationships组合多种关系类型并从两种关系中返回数据
【发布时间】:2019-10-16 14:42:47
【问题描述】:

所以,我目前正在编写一个 Cypher 查询,我想在其中获取数据库中的所有条目及其关系,以便将它们导入 Cytoscape 以进行进一步分析。

我想将两种关系类型组合到一个变量中,对它们使用 WHERE 操作并返回结果。假设我想根据用户花了多少钱(例如收藏版)或他是否真的设法观看了这部电影来获取有趣电影的列表。

现在,我的查询看起来像这样,based on this example:

MATCH (p:Person)-[rel:`watched`|`bought`]->(c:Movie)
WHERE
(rel.watch_min >= 50) or (rel.bought_price > 10)
RETURN p, rel, c

现在,在 Neo4j 浏览器中,这可以正常工作。但是rel 的输出只有watched 关系的关系属性,而不是组合的关系属性。

查询需要是什么样子才能使rel 包含来自watchedbought 的两个属性?

我主要想写的是这样的:

MATCH (p:Person)-[r1:`watched`|r2:`bought`]->(c:Movie)
WHERE
(rl.watch_min >= 50) or (r2.bought_price > 10)
RETURN p, r1, r2, c

但不幸的是,这是无效的语法。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    如果我创建一些示例数据:

    CREATE
      (p:Person{id: 123})-[:watched{watch_min: 60}]->(m:Movie{name:'Foo'}),
      (p)-[:bought{bought_price:99}]->(m);
    

    并执行您的第一个查询,我得到以下结果:

    ╒══════════╤═══════════════════╤══════════════╕
    │"p"       │"rel"              │"c"           │
    ╞══════════╪═══════════════════╪══════════════╡
    │{"id":123}│{"bought_price":99}│{"name":"Foo"}│
    ├──────────┼───────────────────┼──────────────┤
    │{"id":123}│{"watch_min":60}   │{"name":"Foo"}│
    └──────────┴───────────────────┴──────────────┘
    

    因此,您的查询运行良好,并且返回了两种关系类型。

    如果你真的想合并一对节点之间所有关系的属性,可以使用APOC函数apoc.map.mergeList进行合并:

    MATCH (p:Person)-[rel:watched|bought]->(c:Movie)
    WHERE (rel.watch_min >= 50) OR (rel.bought_price > 10)
    RETURN p, c, apoc.map.mergeList(COLLECT(rel)) AS props;
    

    返回这个结果:

    ╒══════════╤══════════════╤══════════════════════════════════╕
    │"p"       │"c"           │"props"                           │
    ╞══════════╪══════════════╪══════════════════════════════════╡
    │{"id":123}│{"name":"Foo"}│{"bought_price":99,"watch_min":60}│
    └──────────┴──────────────┴──────────────────────────────────┘
    

    但是,如果多个关系具有相同的属性,那么这种方法使您无法控制最终是哪一个。

    【讨论】:

    • 哦,是的,我搞砸了这个例子,对不起。 WHERE 的条件取决于这两个属性,例如WHERE (rel.watch_min >= 50) OR (rel.watch_min < 30 and rel.bought_price > 10),假设有多个关系来自或去往存在这些属性的两个节点。以您的示例为例:MATCH (p:Person)-[rel:`watched`|`bought`]->(c:Movie) WHERE (rel.watch_min >= 50) OR (rel.watch_min > 55 and rel.bought_price > 10) RETURN p, c, rel 这是我想要的查询,但这仅返回 watch_min 而不是其他属性。
    • 第1点:我们给(rel.watch_min >= 50)命名为“A”,给(rel.watch_min > 55 and rel.bought_price > 10)命名为“B”。如果 B 为真,那么 A 也为真。所以 (A || B) 实际上在逻辑上与 A 本身是相同的。第 2 点:您使用的 Cypher 代码也存在一个微妙的问题,但您可能应该打开一个新问题以减少混乱。
    • 该死,我又把第二个代码中的值弄乱了,这个值应该是 30 就像在第一个代码块中一样。当然 watch_min 应该小于 50,但是是的,你看我的大脑在这一点上相当混乱。将正确重新打开并仔细花时间校对...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 2021-04-13
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    相关资源
    最近更新 更多