Q:

Shortening optional match query

I have a query here that I would like shortening if possible.
The query says that if I post a document, or someone in my department posts a document I would like to return it, if either of those 2 criteria aren't met then nothing is returned and all is good. 
But I don't like the way I have had to do it, so could someone take a quick look and tell me if there is a better way please
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

As I have to return document, or document2, and me or me2 depending on which match gets a hit it makes things a little messy, is there a way of making it cleaner, so which ever match gets a hit I return document and me?
Thanks

A:

In this case I would use a zero-length path as a sort of proxy to an optional match. Consider this example dataset:
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);

In the case of document 1, you shared it so we want it to be returned with you as the sharer. In the case of document 2, your colleague shared it so we want it to be returned with your colleague as the sharer. In the case of document 3, we want no results as neither you nor your colleague shared the document.
We can write a single query that covers all three scenarios by using the zero-length path when matching on the [:IN_DEPARTMENT_WITH] relationship.
Document 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

Document 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

Document 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.

Note that you are sometimes the "colleague"; in the case that you shared the document you are matched as colleague with a length-zero path. You can play with it live here: http://console.neo4j.org/r/yhyrqu

