2016-03-11 1 views
0

Étant donné un schéma de Neo4j similaire àNeo4j: plusieurs chefs d'accusation de plusieurs correspondances

(:Person)-[:OWNS]-(:Book)-[:CATEGORIZED_AS]-(:Category) 

Je suis en train d'écrire une requête pour obtenir le nombre de livres appartenant à chaque personne, ainsi que le nombre de livres dans chaque catégorie afin que je puisse calculer le pourcentage de livres dans chaque catégorie pour chaque personne.

J'ai essayé requêtes le long des lignes de

match (p:Person)-[:OWNS]-(b:Book)-[:CATEGORIZED_AS]-(c:Category) 
where person.name in [] 
with p, b, c 
match (p)-[:OWNS]-(b2:Book)-[:CATEGORIZED_AS]-(c2:Category) 
with p, b, c, b2 
return p.name, b.name, c.name, 
count(distinct b) as count_books_in_category, 
count(distinct b2) as count_books_total 

Mais le plan de requête est absolument horrible en essayant de faire le deuxième match. J'ai essayé de trouver différentes façons d'écrire la requête afin que je puisse faire les deux comptages différents, mais je n'ai pas trouvé autre chose que de faire deux matchs. Mon schéma ne concerne pas vraiment les gens et les livres. La relation: CATEGORIZED_AS dans mon exemple est en fait quelques options de relation différentes, spécifiées comme [: option1 | option2 | option3]. Donc, dans mon deuxième match, je répète les options de relation de sorte que mon compte total est contraint par eux.

Des idées? Cela ressemble à Neo4j - apply match to each result of previous match mais il ne semblait pas y avoir une bonne réponse pour celui-là.

Répondre

1

UNWIND est votre ami ici. Tout d'abord, calculez le nombre total de livres par personne, en les collectant au fur et à mesure. Ensuite, décomprimez-les afin de pouvoir faire correspondre les catégories auxquelles ils appartiennent. Agréger par catégorie et par personne, et vous devriez obtenir le nombre de livres dans chaque catégorie, pour une personne

match (p:Person)-[:OWNS]->(b:Book) 
with p,collect(b) as books, count(b) as total 
with p,total,books 
unwind books as book 
match (book)-[:CATEGORIZED_AS]->(c) 
return p,c, count(book) as subtotal, total