【问题标题】:How can I run a multiple-MATCH search without returning null?如何在不返回 null 的情况下运行多个 MATCH 搜索?
【发布时间】:2021-01-02 07:05:47
【问题描述】:

您好,如果您想了解我将要参考的图表,我有一个示例查询:

CREATE (u:User {name: "Tim Cook"})-[:FOLLOWS]->(t:Thing {name: "Italy"}), (t)<-[:TAGGED]-(p:Post {name: "Post 1"})<-[:WROTE]-(u1:User {name: "Elon Musk"}), (u)-[:FOLLOWS]->(u2:User {name: "Oprah"})-[:WROTE]->(p1:Post {name: "Post 2"}), (u)-[:FOLLOWS]->(u3:User {name: "Joe Biden"})-[:WROTE]->(p2:Post {name: "Post 3"})

也在这里:

我正在尝试获取用户直接关注作者(“写”帖子的人)或该人关注帖子中“标记”的事物的所有帖子。

因此,在示例查询中,如果您是 Tim Cook,您应该收到帖子 2 和 3,因为您直接关注作者,而帖子 1 因为您关注在该帖子中被标记的意大利。

我一直在到处寻找,很难找到。降落在这里。我正在使用“可选”,这样如果用户没有关注任何人,第一个不会使整个查询崩溃,或者如果他们没有关注任何事情,第二个不会崩溃。但是,按照我在下面的操作方式,它会为任何一个为空的查询返回 Null。

因此,如果第一部分没有匹配项,而第二部分没有 6 个匹配项,我将得到一个长度为 7 的数组。[null, post1, post2, ...post6]。

请问我应该怎么做呢?提前谢谢!

OPTIONAL MATCH (this)-[:FOLLOWS]->(u1)-[:WROTE]->(post:Post)
RETURN post
ORDER BY post.id
UNION
OPTIONAL MATCH (this)-[:FOLLOWS]->(t:Thing)<-[:TAGGED]-(post:Post)
RETURN post
ORDER BY post.id

this 指的是上例中的 Tim Cook 用户节点。

如果用户关注作者(“写”的用户),我也想返回。所以我想我可以添加一个“EXISTS”或者有没有办法指定哪个查询返回了一个帖子?例如。如果帖子是由上面的第一个 MATCH 返回的,那么他们显然跟随作者。如果第二次返回,而不是第一次返回,那么他们不会。解决此查询的最佳方法是什么/我应该怎么做呢?提前谢谢!

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    您可以将路径中间的节点(用户或标签)视为通用对象,因此从那里使用多关系类型模式匹配:

    MATCH (u:User {name: "Tim Cook"})
    MATCH (u)-[:FOLLOWS]->(thing)-[:WROTE|TAGGED]-(p:Post)
    RETURN p.name
    
    ╒════════╕
    │"p.name"│
    ╞════════╡
    │"Post 3"│
    ├────────┤
    │"Post 2"│
    ├────────┤
    │"Post 1"│
    └────────┘
    ```
    
    From there, if you want to know if the user is following the author, it's just plain logic, you return if the node in the middle is of type 'User' (which would validate the assumption since the first relationship is FOLLOWS thing)
    
    ```
    MATCH (u:User {name: "Tim Cook"})
    MATCH (u)-[:FOLLOWS]->(thing)-[:WROTE|TAGGED]-(p:Post)
    RETURN p.name, ('User' IN labels(thing)) AS followingAuthor
    
    ╒════════╤═════════════════╕
    │"p.name"│"followingAuthor"│
    ╞════════╪═════════════════╡
    │"Post 3"│true             │
    ├────────┼─────────────────┤
    │"Post 2"│true             │
    ├────────┼─────────────────┤
    │"Post 1"│false            │
    └────────┴─────────────────┘
    ```
    
    
    

    【讨论】:

    • 哇!将(事物)放在那里而不是(事物),然后使这种关系变得没有方向,这是一个很好的选择!使它可以是任何节点,这真的很聪明。非常感谢!
    • 如果有人关注了作者,同时也关注了在帖子中标记的事物,目前他们都返回。所以我放了 RETURN DISTINCT p,这是避免重复的最佳选择(似乎是这样!)?再次感谢您!
    • 这是一个不错的选择。您还可以在使用聚合函数时利用 Cypher 的隐式 GroupBy,例如 RETURN p, count(*) AS score,以防您想对结果进行排名
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多