Reputation: 395
I have a graph with Books, Chapters, and Characters. Books contain Chapters, and Chapters mention Characters. I want to write a query showing me the 10 Characters that appear in most books, together with the books they appear in.
Supposing that my problem is a bit simpler, I can easily write a query showing me the 10 Characters that appear in most chapters:
MATCH (chapter)-[:MENTIONS]->(character)
RETURN character,
COLLECT(chapter) as chapters
ORDER BY SIZE(chapters) DESC
LIMIT 10
This query above is working fine. Now I'm attempting to write a similar query that shows books rather than chapters:
MATCH (book)-[:CONTAINS]->(chapter)-[:MENTIONS]->(character)
RETURN character,
COLLECT(book) as books
ORDER BY SIZE(books) DESC
LIMIT 10
This query seems to work fine, but it just reports a bunch of characters and books without any relationship, because there is no direct relationship between books and characters. Can neo4j infer these indirect relationships and show them in the query without me having to modify the data and manually insert for each pattern
(book)-[:CONTAINS]->(chapter)-[:MENTIONS]->(character)
a new relationship
(book)-[:TALKS_ABOUT]->(character)
?
Upvotes: 4
Views: 2194
Reputation: 29167
It's look like you need virtual relationships. You can try apoc.create.vRelationship
:
MATCH (book)-[:CONTAINS]->(chapter)-[:MENTIONS]->(character)
WITH character,
COLLECT(distinct book) as books
ORDER BY SIZE(books) DESC LIMIT 10
UNWIND books as book
CALL apoc.create.vRelationship(book,'TALKS_ABOUT',{}, character) yield rel
RETURN character, collect(rel) as rels
Upvotes: 6