Reputation: 69
I am trying to query the neighborhood at a certain distance around a topic node. The twist, is I do not want to follow relationships from nodes with a certain attribute. Any query needs to run on graphs in the millions of nodes and edges (which rules out collecting paths).
I think I have a query that will do it:
MATCH (topic: attribute)-[r:describedBy|influences*0..2]-(n: attribute)
WHERE id(topic) IN [239930]
WITH n, r as rels, topic
MATCH (n: attribute)-[r:describedBy|influences]->()
WHERE NOT n.key in ['enrichment', 'classification'] AND r in rels
WITH n, r, collect(r) as rels, topic
MATCH path = shortestpath((topic)-[*..2]-(n))
WHERE extract(rel IN rels(path) | rel) as r WHERE r in rels
WITH r, extract(n IN nodes(path) | n) as nodes
RETURN count(DISTINCT r), count(DISTINCT nodes)
The problem is trying to compare collections of relationships. Specifically:
Type mismatch: expected Collection<Collection<Relationship>> but was Collection<Relationship> (line 8, column 43 (offset: 369))
"WHERE extract(rel IN rels(path) | rel) in rels "
I have run into this 'collection of collection of relationships' problem in multiple attempts to create this query.
How can I either A: fix the collection of collection of relationships
problem or B: rewrite the query such that it returns the neighborhood around one or more nodes at a given distance and without following relationships from nodes with specific properties?
[EDIT]
Based on @cybersam's recommendation, the query is now:
WHERE NOT n.key in ['enrichment', 'classification'] AND r in rels
WITH n, r, collect(r) as rels, topic
MATCH path = shortestpath((topic)-[*..2]-(n))
WHERE [r2 IN rels(path) WHERE r2 in rels]
WITH r, extract(n IN nodes(path) | n) as nodes
RETURN count(DISTINCT r), count(DISTINCT nodes)
The problem is that this returns 47242 relationships and 47242 edges. It would appear it's returning the edges from the collection of path rather than from the sub-query above, (which has a count of 100103 edges or so from previous experimentation).
Upvotes: 1
Views: 105
Reputation: 66957
First of all, you have syntax errors in this line of your question's query:
WHERE extract(rel IN rels(path) | rel) as r WHERE r in rels
You probably actually used WITH
instead of the leading WHERE
-- as that would result in the error you reported:
WITH extract(rel IN rels(path) | rel) as r WHERE r in rels
Now, assuming that I am correct above:
extract(rel IN rels(path) | rel)
is the same as rels(path)
, which makes using extract()
a waste of time. I suspect that you actually meant to extract something else. Note that, currently, the resulting r
is a collection of relationships. r
is a collection of relationships, the r in rels
clause would require that rels
be a collection of collection of relationships. But it is actually a collection of relationships, hence the error.The solution might be as easy as fixing your extract()
clause. I don't know enough about your problem domain to know how to do that, but hopefully this is enough to point you in the right direction.
[EDIT]
Based on the clarification from @Gabe, this might be the correct replacement for the line in question:
WHERE all(r IN rels(path) WHERE r in rels)
Upvotes: 1