简体   繁体   中英

Finding only nodes that have more than one incoming relationship in neo4j using cypherquery

i have a neo4j database for learning this new fangled graph technology and i made nodes following this structure

(n:NewsArticle) -[r:about_place]-> (l:Location)

now what i want is slightly complicated/convoluted (or i seem to think it is) and being new to cypher i'm not able to completely express myself in this new syntax. please bear with me.

basically i have articles tagged with lots of locations. now, for a given day i have found all articles that are tagged with a certain location. once i have them, Now for those articles, i want to find out what other locations they are tagged with.

this code seems to do what i want it. (yaay)

MATCH (n:NewsArticle{date:"Jun-30-2015"})-[]->(l:Location{name:"India"})
MATCH (n:NewsArticle)-[r:about_place]->(m:Location)
return n,m

at this point i end up with 8 Locations and 132 news articles.

Now for the Tricky part. most of the 132 articles that i have have about_place relationships pointing to only 1 of the 8 locations, i do not want this. I want to find Articles within this set that have relationships to at least 2 of the Locations that i have found.

i came up with this query,

MATCH (n:NewsArticle{date:"Jun-30-2015"})-[]->(l:Location{name:"India"})
MATCH (n:NewsArticle)-[r:about_place]->(m:Location)
WITH m, count(r) as rel_cnt
WHERE rel_cnt > 2
MATCH (a:NewsArticle{date:"Jun-30-2015"})-[r:about_place]->(m:Location)
return a,m

it does give me some results but it does not do what i want. but if i change the a to n (to refer to the first 2 match statements) it becomes a syntax error although i feel that then it should give me the result i want.

tl;dr i dont want to see location nodes that have only one news article pointing to them

This query should return all the NewsArticle nodes with the date property of "Jun-30-2015" that have an :about_place relationship with Location India and at least one other location:

MATCH (n:NewsArticle {date:"Jun-30-2015"})-[:about_place]->(:Location {name: "India"})
MATCH (n)-[r:about_place]->(l:Location)
WITH collect(n) AS articles, l, count(r) AS num WHERE num > 2
RETURN l, articles, num

Try:

MATCH (n:NewsArticle {date:"Jun-30-2015"})-[:about_place]->(:Location {name: "India"})
MATCH (n)-[r:about_place]->(l:Location)
WITH n, count(r) as num 
WHERE num > 2
MATCH (n)-[:about_place]->(l:Location)
RETURN n, l

You might want to exclude the original location from the result, for that you need to add an additional filter before the final RETURN.

found the answer as the collect() statement which lets you carry variables through the WITH pipe.

MATCH (n:NewsArticle{date:"Jun-30-2015"})-[:about_place]->(l:Location{name:"India"})
MATCH (n:NewsArticle)-[r:about_place]->(loc:Location)
WITH loc,collect(n) as article, count(r) as num WHERE num > 2
RETURN loc,article

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM