Cypher: Filter by relationship properties?

3,726 views
Skip to first unread message

Axel Morgner

unread,
Jun 5, 2012, 2:58:17 AM6/5/12
to ne...@googlegroups.com
Good mornin',

we're about to integrate Cypher queries into structr (we're deeply impressed by and love Cypher!!).

Now we'd like to filter the results by relationship properties. [1] says, that you can only filter by relationship type.

Use Case: Return all nodes of type 'Page' which have child nodes that contain the word 'test' in their 'content' attribute. This works quite well.

START n=node:index(type='Page')
MATCH n-[r:CONTAINS*]->child
WHERE (child.type = 'Content' AND child.content =~ /.*test.*/)
RETURN DISTINCT n


But now we like Cypher to follow relationships with a certain property value only.

Like this:

START n=node:index(type='Page')
MATCH n-[r:CONTAINS*]->child
WHERE (r.foo = 'bar' AND child.type = 'Content' AND child.content =~ /.*test.*/)
RETURN DISTINCT n

Or this:

START n=node:keywordAllNodes(type='Page')
MATCH n-[r:CONTAINS*, r.foo = 'bar']->child
WHERE (child.type = 'Content' AND child.content =~ /.*test.*/)
RETURN DISTINCT n


Is there any way to achieve this?

We're using 1.7.1, but could use 1.8M* too, if needed.

Thanks
Axel

[1] http://docs.neo4j.org/chunked/1.7.1/query-where.html#where-filter-on-relationships

Andres Taylor

unread,
Jun 5, 2012, 3:15:51 AM6/5/12
to ne...@googlegroups.com
On Tue, Jun 5, 2012 at 8:58 AM, Axel Morgner <ax...@morgner.de> wrote:
Good mornin',

we're about to integrate Cypher queries into structr (we're deeply impressed by and love Cypher!!).

Thank you. And right back at ya - structr looks really neat! 
 
Now we'd like to filter the results by relationship properties. [1] says, that you can only filter by relationship type.

That's when you are using patterns in the WHERE clause. It does not apply to this example. (And, I'm working on making this part much more powerful as we speak)
 
Use Case: Return all nodes of type 'Page' which have child nodes that contain the word 'test' in their 'content' attribute. This works quite well.

START n=node:index(type='Page')
MATCH n-[r:CONTAINS*]->child
WHERE (child.type = 'Content' AND child.content =~ /.*test.*/)
RETURN DISTINCT n


But now we like Cypher to follow relationships with a certain property value only.

Like this:

START n=node:index(type='Page')
MATCH n-[r:CONTAINS*]->child
WHERE (r.foo = 'bar' AND child.type = 'Content' AND child.content =~ /.*test.*/)
RETURN DISTINCT n


The reason this does not work is because of that little star symbol after contains. Your symbol `r` does not point to a single relationship, it's pointing to a collection containing all the relationships between `n` and `child`. If you want all relationships to have the foo property set to "bar", you can use the ALL function:

where all(rel in r WHERE rel.foo = 'bar')...

Does that make sense?

Andrés

Axel Morgner

unread,
Jun 5, 2012, 6:16:57 PM6/5/12
to ne...@googlegroups.com
Yes, that makes sense and works fine!
Thanks a lot!

Reply all
Reply to author
Forward
0 new messages