Cypher: filtering nodes if a relation exists

1,275 views
Skip to first unread message

Luanne Coutinho

unread,
May 1, 2012, 1:11:11 PM5/1/12
to ne...@googlegroups.com
Hi,

How do you filter out nodes from the result of a cypher query based on whether a relation exists or not?
This is an example of what I was trying to do:

start n = node(13), interest=node(17)
match (n)<-[:knows|works_with]-(person)-[:friend]-(friend)-[:knows|works_with]-(friendProfile)
where not (friendProfile)-[:has]->(interest)<-[:has]->(n))
return friendProfile.name as name

I was trying to say- do not give me friendProfiles that have the same interest as the start node n.

Thanks
Luanne

Peter Neubauer

unread,
May 1, 2012, 1:15:34 PM5/1/12
to ne...@googlegroups.com
Luanne, is

http://docs.neo4j.org/chunked/snapshot/cypher-cookbook-similar-favorites.html
along these lines?

Cheers,

/peter neubauer

G:  neubauer.peter
S:  peter.neubauer
P:  +46 704 106975
L:   http://www.linkedin.com/in/neubauer
T:   @peterneubauer

If you can write, you can code - @coderdojomalmo
If you can sketch, you can use a graph database - @neo4j

Josh Adell

unread,
May 1, 2012, 3:40:34 PM5/1/12
to Neo4j
Maybe:

start n = node(13), interest=node(17)
match (n)<-[:knows|works_with]-(person)-[:friend]-(friend)-[:knows|
works_with]-(friendProfile)-[h?:has]->(interest)<-[:has]->(n)
where h is null
return friendProfile.name as name

-- Josh

Luanne Coutinho

unread,
May 1, 2012, 1:24:13 PM5/1/12
to ne...@googlegroups.com
Hi Peter,

That's what I thought- but if you take a look at the expression in my where clause, its more than 2 nodes with 1 relation:

start n = node(1), interest=node(7)
match (n)<-[:knows|works_with]-(person)-[:friend]-(friend)-[:knows|works_with]-(friendProfile)
where not (friendProfile)-[:has]->(interest)<-[:has]->(n)
return friendProfile.name as name

That seems to be the problem- on the console, I get "Error, expected return clause"


I don't have any interests there, but a fictitious interest of node 7 still produces that error with the query:

start n = node(1), interest=node(7)
match (n)<-[:knows|works_with]-(person)-[:friend]-(friend)-[:knows|works_with]-(friendProfile)
where not (friendProfile)-[:has]->(interest)<-[:has]->(n)
return friendProfile.name as name

Or I might have had too much cypher for today- let me know if you spot something silly.

Thanks
Luanne

Michael Hunger

unread,
May 1, 2012, 5:33:03 PM5/1/12
to ne...@googlegroups.com
Imho the where filtering can only check for direct relationships, not paths.


Michael

Luanne Coutinho

unread,
May 2, 2012, 1:05:28 AM5/2/12
to ne...@googlegroups.com
Josh, thanks- I will try that out.

-Luanne

Andres Taylor

unread,
May 2, 2012, 3:12:24 AM5/2/12
to ne...@googlegroups.com
On Tue, May 1, 2012 at 11:33 PM, Michael Hunger <michael...@neotechnology.com> wrote:
Imho the where filtering can only check for direct relationships, not paths.

This is exactly where sub-queries would be useful.

Andrés 

Romiko Derbynew

unread,
May 24, 2012, 8:30:20 PM5/24/12
to Neo4j
Hi Guys,


I think this feature will be useful, reason being, is you can have
more generic reltionship names e.g.

AuditCategoryNode->HAS_AUDIT->ClientNode<-IS_CLIENT
AuditCategoryNode->HAS_AUDIT->EmployeeNode<-IS_EMPLOYEE


So if I ran a report ONLY for audit nodes based on clients, it would
be nice to say get me all HAS_AUDIT where the node has an incoming
relationship IS_CLIENT.


Otherwise, it has to be done like this
AuditCategoryNode->HAS_CLIENT_AUDIT->ClientNode
AuditCategoryNode->HAS_EMPLOYEE_AUDIT->EmployeeNode

Thoughts guys? Would be nice to have a feature SIMILAR to gremlins
BACK statement, where you can traverse to CLIENT, go up to IS_CLIENT
and then kick a BACK step which filters out only CLIENTS :) I guess
this would have to be a subfilter, or perhaps it can currently be
done?





On May 2, 3:12 am, Andres Taylor <andres.tay...@neotechnology.com>
wrote:
> On Tue, May 1, 2012 at 11:33 PM, Michael Hunger <
>

Andres Taylor

unread,
May 25, 2012, 4:11:39 AM5/25/12
to ne...@googlegroups.com
On Fri, May 25, 2012 at 2:30 AM, Romiko Derbynew <rom...@gmail.com> wrote:
Hi Guys,


I think this feature will be useful, reason being, is you can have
more generic reltionship names e.g.

AuditCategoryNode->HAS_AUDIT->ClientNode<-IS_CLIENT
AuditCategoryNode->HAS_AUDIT->EmployeeNode<-IS_EMPLOYEE


So if I ran a report ONLY for audit nodes based on clients, it would
be nice to say get me all HAS_AUDIT where the node has an incoming
relationship IS_CLIENT.

Is something like this what you're after?

START  AuditCategoryNode=node(...)
MATCH AuditCategoryNode-[:HAS_AUDIT]->ClientNode
WHERE ClientNode<-[:IS_CLIENT]-()
RETURN ClientNode

Andrés
Reply all
Reply to author
Forward
0 new messages