Reputation: 2981
I have a query which is going over a graph of companies, groups, watchlists and members. See the gist of dummy data in geoff format for the data in the database. I've also setup a console neo4j for anyone to play with.
The aim of the query is to get a list of groups as well as the number of members (a member is a generic term for a person or a company) that have a relationship with the group and its related watchlists.
With the query below I'm getting the correct alert numbers but I'm missing "Empty group" because it doesn't have any members or watchlists. I've tried to make various relationships optional but it ends up getting the count of alerts wrong because it's using watchlists that are related to the group. I've tried countless ways of writing the query but just can't get around the problem.
START company=node(233), group=node:node_auto_index("_type:group")
MATCH company-[:OWNS]->group-[?:LINKED_TO]->watchlist-[:WATCHING|APPOINTMENT*1..2]-member<-[:WATCHING]-group
RETURN group, COUNT(DISTINCT(member)) as alerts
ORDER BY group.name
Ideally I'd like to make the entire path segment which connects a group to members and then onto watchlists as optional however I can't find out how to do that in the docs or it's just not possible. Is there any other way around this other than doing two queries?
The correct results are that the groups and alerts should be:
Big Dot Coms, 1
Big Hitters, 4
Empty group, 0
Old CEOs, 1
Upvotes: 1
Views: 949
Reputation: 3435
I hope i understood correctly, but i think this is what you are looking for:
START company=node:node_auto_index("name:\"Finance Ltd\""), group=node:node_auto_index("_type:group")
MATCH company-[:OWNS]->group-[?:WATCHING]->member,group-[?:LINKED_TO]->watchlist
WITH group, member, watchlist
MATCH watchlist-[:WATCHING|APPOINTMENT*1..2]-member
RETURN group, count(distinct( member))
ORDER BY group.name
Basically you can use the WITH
keyword to gradually build up your query. Firstly get all group<->member pairings including non existing ones. Then optionally match in watchlists and then use a final match to apply your condition and return the results.
Upvotes: 2
Reputation: 5918
i'm afraid this will never be possible with cypher, because of the traversal pattern :
- you want to count empty groups, this means that there is no node member
. imagine this simple backtrack: as soon as the search algorithm has no more node to step into, it simply returns one step back. since there is no node member
the match pattern will never match the whole pattern company-[:OWNS]->group-[?:LINKED_TO]->watchlist-[:WATCHING|APPOINTMENT*1..2]-member<-[:WATCHING]-group
but only company-[:OWNS]->group-[?:LINKED_TO]->watchlist
. thus, when the match pattern is not found, there is also no data in the result.
-i suggest to finish the match pattern at the counted nodes, i.e. something like company-[:OWNS]->group-[?:LINKED_TO]->watchlist-[:WATCHING|APPOINTMENT*1..2]-member
. than you may get the zero in the count result. i tried to play with the console but it seems it does not have any empty group in its data, so i can't create the final query for you.
Upvotes: 1