I have a pretty 'simple' Graph which I interact with via Spring Data (and the Neo4J browser).
Currently the Graph has nodes of Books, Publishers and Authors (with relations AUTHOR_OF and PUBLISHES respectivly). A Book can have a single Publisher and multiple Authors.
I'm trying to write a query to find all potential books, their authors and their publisher (if they have them) based on various matches: WHERE unique Id match OR does it match the ISBN OR if the book has an author does it match on book title AND author.
However, the result set returned seems to vary based on the number of relationships as well as the number of criteria it's matched.
My sample data is as follows:
MATCH (bo:Book)
OPTIONAL MATCH (au:Author)-[r:AUTHOR_OF]->(bo:Book)<-[s:PUBLISHES]-(pu:Publisher)
RETURN bo, r, au, s, pu
Returns three records:
MATCH (bo:Book)
WHERE bo.bookId={book 1 ID}
OPTIONAL MATCH (au:Author)-[r:AUTHOR_OF]->(bo:Book)
OPTIONAL MATCH (bo:Book)<-[s:PUBLISHES]-(pu:Publisher)
RETURN bo, r, au, s, pu
Returns two records.
MATCH (bo:Book)
WHERE bo.bookId={book 2 ID}
OPTIONAL MATCH (au:Author)-[r:AUTHOR_OF]->(bo:Book)
OPTIONAL MATCH (bo:Book)<-[s:PUBLISHES]-(pu:Publisher)
RETURN bo, r, au, s, pu
Returns Book 2
MATCH (bo:Book)
WHERE bo.bookId={book 2 ID}
OR bo.isbn={book 1 ISBN}
OPTIONAL MATCH (au:Author)-[r:AUTHOR_OF]->(bo:Book)
OPTIONAL MATCH (bo:Book)<-[s:PUBLISHES]-(pu:Publisher)
RETURN bo, r, au, s, pu
Returns three records
So I appear to be on the right track... However there are couple of things I'm now stumped on.
I expect the answer lies within a combination of WITH
, COLLECT()
and DISTINCT
but I haven't been successful.
Try something like this, you will need to COLLECT
, to collect all authors in a list:
MATCH (bo:Book)
WHERE bo.bookId={bookID} OR bo.isbn={bookISBN} OR (bo.title={bookTitle} AND (bo)<-[:AUTHOR_OF]-(:Author{name:{authorName}}))
OPTIONAL MATCH (au:Author)-[r:AUTHOR_OF]->(bo:Book)
OPTIONAL MATCH (bo:Book)<-[s:PUBLISHES]-(pu:Publisher)
RETURN bo, pu, collect(au) AS authors