Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
05-19-2021 04:31 AM
I am having the scenario where I have multiple labels(Hashtags) and I need to get the exact mutual nodes(contributors) which are contributing on all the selected labels(Hashtags).
The Query I am using is
"WITH ["#Hashtag1","#Hashtag2","#Hashtag3"] as ids MATCH (n1:Hashtag),(n2:Hashtag) WHERE n1.id in ids and n2.id in ids and n1.id<>n2.id MATCH p = ((n1)-[*..2]-(n2)) RETURN p limit 2000"
In my use case I have 2 labels with the name (hashtag, contributor) and the relationship between them is "contributed_on".
What I want is to get all the mutual nodes of above three selected hashtags (labeled green in attached picture) in WITH clause, but from above query I am getting the data of hastag1 mutual to hashtag2 mutual, but I want only the mutual contributors(labeled pink within circle) as I highlighted in attached picture.
P.S : We may have any number of hashtags as input so I want the query to be dynamic also.
05-19-2021 08:25 AM
Could you maybe look at the intersection of results lists as described here? Also, this SO post as well as this one might help.
05-19-2021 10:44 PM
Well thanks,
I have tried these, but unable to get the desired result. Can you help me out to write the query.
Thanks
05-20-2021 01:33 PM
OK. So I created this toy graph, where I have blue nodes that I have called sources (like your green nodes) and orange nodes called targets (your pink nodes). It looks like this:
The simple way to do this query would be with something like
MATCH (n1:Source {name: 'n1'})-->(x:Target)
WITH n1, x
MATCH (n2:Source {name: 'n2'})-->(x:Target)
WITH n2, x
MATCH (n3:Source {name: 'n3'})-->(x:Target)
WITH n3, x
RETURN x.name
This totally works for this toy case where there are just 3 of your green nodes. But suppose you have way more than 3 and want this to scale. Then you could write it like this:
MATCH (n:Source) WHERE n.name in ['n1', 'n2', 'n3']
WITH collect(n) AS sourceNodes
MATCH (x:Target)
WHERE ALL (n in sourceNodes WHERE (x)<-[:CONNECTS]-(n))
RETURN x.name
In this case, you are assembling a list of those source nodes and using a predicate (ALL
) to check them against.
As the graph gets larger, you will probably want to sort the source nodes in order of least connections to most so you can sift through the potential targets faster. To do this, try:
WITH ['n1', 'n2', 'n3'] AS sourceNodes
UNWIND sourceNodes AS sn
MATCH (n:Source {name:sn})
WITH n ORDER BY SIZE( (n)-[:CONNECTS]-() ) ASC
WITH collect(n) AS sources
WITH head(sources) AS first, TAIL(sources) AS rest
MATCH (first)-[:CONNECTS]->(x:Target)
WHERE ALL(n IN rest WHERE (n)-[:CONNECTS]->(x))
RETURN x.name
Please let me know if this solves the problem. Good luck!
07-14-2021 05:47 AM
Hi ,
I tested your created toy and its very helpful. I am so close to my desired solution but could you help me with returning the results in a graph form. Right now you are only returning "x.name" but what if I want to return all the nodes with the relation also.
07-14-2021 07:26 AM
Since you know that all nodes will be connected to x1, x2, and x3, returning the source node adds no value. So we could modify the query as follows:
WITH ['n1', 'n2', 'n3'] AS sourceNodes
UNWIND sourceNodes AS sn
MATCH (n:Source {name:sn})
WITH n ORDER BY SIZE( (n)-[]-() ) ASC
WITH collect(n) AS sources
WITH head(sources) AS first, TAIL(sources) AS rest
MATCH (first)-[r]->(x:Target)
WHERE ALL(n IN rest WHERE (n)-[]->(x))
RETURN r, x.name
This should return both the nodes we are interested in (x1, x2, and x3) plus the relation types between them, since we have replaced the given relationship type [:CONNECTS]
with the variable [r]
.
Please let me know if that doesn't answer the question!
07-14-2021 11:16 PM
The relationship in the *
Any*
clause for my situation is some how like this
WHERE ALL(n IN rest WHERE (n)-[*..2]->(x))
.
What I really want is to make it return in the graphical form where we have all the nodes and the relationships pointed towards each other(Please see image of the original question posted)
.
As we do it in normal scenarios
`MATCH p = ((n1)-[*..2]-(n2))`
`Return p`
Some thing like this.
07-30-2021 08:00 AM
Maybe we are making things too complicated. Please let me know if this solves your problem:
MATCH (s:Source) WITH COUNT(s) AS num_sources
MATCH (n:Source)-[]->(t:Target)
WHERE SIZE(()-[]->(t)) = num_sources
RETURN n, t
All the sessions of the conference are now available online