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:'[email protected]'})
optional match(document2:Document{id:6})-[:SHARED]-(me2:Person{Email:'[email protected]'})
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
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:"[email protected]"}),
(colleague:Person {Email:"[email protected]"}),
(nonColleague:Person {Email:"[email protected]"}),
(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:"[email protected]" })-[:IN_DEPARTMENT_WITH*0..1]-(colleague)
RETURN colleague.Email, doc.id;
colleague.Email doc.id
[email protected] 1
Document 2:
MATCH (colleague:Person)-[:SHARED]->(doc:Document { id:2 }),
(:Person { Email:"[email protected]" })-[:IN_DEPARTMENT_WITH*0..1]-(colleague)
RETURN colleague.Email, doc.id;
colleague.Email doc.id
[email protected] 2
Document 3:
MATCH (colleague:Person)-[:SHARED]->(doc:Document { id:3 }),
(:Person { Email:"[email protected]" })-[: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