缩短可选匹配查询

Shortening optional match query

我在这里有一个查询,如果可能的话我想缩短它。 查询说,如果我 post 一份文件,或者我部门的某个人 post 一份文件,我想 return 它,如果这两个条件中的任何一个不满足,那么什么都没有returned,一切都很好。 但是我不喜欢我必须这样做的方式,所以有人可以快速看一下并告诉我是否有更好的方法

optional match(document:Document{id:6})-[:SHARED]-()-[:IN_DEPARTMENT_WITH]-(me:Person{Email:'user@outlook.com'})
optional match(document2:Document{id:6})-[:SHARED]-(me2:Person{Email:'user@outlook.com'})
return document,me,document2,me2

因为我必须 return 文档,或文档 2,以及我或我 2,这取决于哪个匹配项被击中,这让事情变得有点混乱,有没有办法让它更干净,所以哪个匹配我 return 文档和我获得成功?

谢谢

在这种情况下,我将使用零长度路径作为可选匹配的一种代理。考虑这个示例数据集:

CREATE (doc1:Document {id:1}),
       (doc2:Document {id:2}),
       (doc3:Document {id:3}),

       (you:Person {Email:"shaine@outlook.com"}),
       (colleague:Person {Email:"nicole@outlook.com"}),
       (nonColleague:Person {Email:"julian@outlook.com"}),

       (you)-[:IN_DEPARTMENT_WITH]->(colleague),
       (you)-[:SHARED]->(doc1),
       (colleague)-[:SHARED]->(doc2),
       (nonColleague)-[:SHARED]->(doc3);

在文档 1 的情况下,您共享了它,因此我们希望它作为共享者返回给您。在文档 2 的情况下,您的同事共享了它,因此我们希望它与作为共享者的您的同事一起返回。对于文档 3,我们不希望有任何结果,因为您和您的同事都没有共享该文档。

我们可以通过在 [:IN_DEPARTMENT_WITH] 关系上匹配时使用零长度路径来编写涵盖所有三种情况的单个查询。

文档 1:

MATCH (colleague:Person)-[:SHARED]->(doc:Document { id:1 }),
      (:Person { Email:"shaine@outlook.com" })-[:IN_DEPARTMENT_WITH*0..1]-(colleague)
RETURN colleague.Email, doc.id;

colleague.Email     doc.id
shaine@outlook.com  1

文档 2:

MATCH (colleague:Person)-[:SHARED]->(doc:Document { id:2 }),
      (:Person { Email:"shaine@outlook.com" })-[:IN_DEPARTMENT_WITH*0..1]-(colleague)
RETURN colleague.Email, doc.id;

colleague.Email     doc.id
nicole@outlook.com  2

文档 3:

MATCH (colleague:Person)-[:SHARED]->(doc:Document { id:3 }),
      (:Person { Email:"shaine@outlook.com" })-[:IN_DEPARTMENT_WITH*0..1]-(colleague)
RETURN colleague.Email, doc.id;

No rows.

请注意,您有时是 "colleague";在您共享文档的情况下,您将匹配为 colleague 和长度为零的路径。你可以在这里现场玩:http://console.neo4j.org/r/yhyrqu

这对你有用吗?

MATCH (me:Person{Email:'user@outlook.com'}), (doc:Document{id:6})
OPTIONAL MATCH (doc)-[r:SHARED]-(me)
WITH me, doc, (CASE WHEN r IS NULL THEN [] ELSE [me] END) AS myself
OPTIONAL MATCH (doc)-[:SHARED]-(p)-[:IN_DEPARTMENT_WITH]-(me)
RETURN doc, COLLECT(p) + myself AS result;

此查询仅匹配 medoc 一次,并合并两个(可能为空的)集合以得出最终的人员集合。如果 MATCH(在第一行)没有找到匹配项,结果将不包含任何行。