st1led
st1led

Reputation: 395

Query to show second degree (indirect) relationships in Neo4j

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

Answers (1)

stdob--
stdob--

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

Related Questions