Retrieve nodes based on relationships count with an exception

Hi,
I have 100000 nodes "Person" and 1000 "Company"
i have relationship types "CEO" , "CTO", "ACCOUNTANT", "WORKER", ....
A person can be related to several companies with all type of rels...
Now, i need to find the top 10 Persons with most connections Except "ACCOUNTANT"
for example:
John is a CEO in 4 companies, CTO in 10 companies and ACCOUNTANT in 20 companies
Jane is CEO in 2 companies, CTO in 10 companies and ACCOUNTANT in 40 companies
We see that Jane has more relationships than John but... if we ignore "ACCOUNTANT" , John has more relationships than Jane
The query should return the top 10 Persons with all relationships (except "ACCOUNTANT") to the companies (including the Company nodes)
Thanks

if I get you right, what you need is the top 10 of a list of number of relations between a person and a company (excluding accountant relations)

did not test but it should be something like

MATCH (p:Person)-[r:CEO|CTO|WORKER]-(:Company)
WITH p, size(collect(r)) as nbRel
return p order by nbRel desc limit 10

Try this. The relationship expression syntax requires version 5.

Match (n:Person)
with n, count{(n)-[:!ACCOUNTANT]-(:Company)} as cnt
Order by cnt desc
Limit 10
Return n

hi Gary, never saw the count{} syntax, can you please point to a documentation reference about it ?

Thanks, but i have more than 20 relationship types' and i don't want to specify all of them except ACCOUNTANT, i want to specify only the exclusion

then use the syntax Gary suggested : [:!ACCOUNTANT]

Hi, Thanks, but it returns only the persons, and i already managed to do it.
What I need to return is the persons , the companies and all the relationships between them
Thanks

MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company)
WITH p, size(collect(r)) as nbRel,collect(distinct type(r)) as rels,collect(distinct c.name) as cies
return p.name,rels,cies order by nbRel desc limit 10

or if you need the nodes


MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company)
WITH p, size(collect(r)) as nb Relorder by nbRel desc limit 10
MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company) return *

You should not have to match twice.

MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company)
WITH p, collect(c) as companies
ORDER BY size(companies) DESC
LIMIT 10
RETURN p as person, companies 

It’s a subquery expression. There are three: count, exists, collect.

you do not return relationships

What I need to return is the persons , the companies and all the relationships between them

oops, try this instead:

MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company)
WITH p, collect(c) as companies, collect(r) as relationships
ORDER BY size(companies) DESC
LIMIT 10
RETURN p as person, companies, relationships

or, if you want the relationships related to its company:

MATCH (p:Person)-[r:!ACCOUNTANT]-(c:Company)
WITH p, collect({company:c, relationship:r}) as companies
ORDER BY size(companies) DESC
LIMIT 10
RETURN p as person, companies

Thank, it's working...
Now, i need to find connections between persons with 2-4 hops of specific relationships or any relationships...
i tried to add this before "RETURN":
MATCH (p)-->(:Company)--(p:Person)
and it doesn't work
Thanks

I think your issue is that your match has 'p' related to 'p', which would be a loop. Don't put 'p' in the end node, as this constrains the node to be the same as the start node 'p', but with a further constraint of being a Person node.

If you want paths that are from 2 to 4 hops between node 'p' and another person, then try the following:

MATCH (p)-[*2..4]-(:Person)

If you provide the entire query and what is wrong, I can try to help further.

Thanks,

To be more specific:
I want to find out if there is a connection between John and Jane based on relationships to companies with 2-4 hops...
I tried this:
MATCH (p {idNumber: 1111111})-[*2..4]-(:Person{idNumber:33333333})RETURN *
Doesn't work

If you are only interested in the existence of the relationship you should use the β€˜exits’ subquery expression. This was added in version 5.4 or 5.6 or there about. You can verify in the docs. It allows you to execute a complicated query and will return true or false corresponding to the query producing at least one record. If the query is a one line match, then you can use the exists function. It is not new.

The following is an example using the exists function since your query consists of a single match.

MATCH(p:Person{number:111111})
RETURN  p, exists( (p)-[*2..4]-(:Person{idNumber:33333333}) ) as exists

Thanks,

But i need the 2 persons and the relationships between them, so i can see how they connected to each other

Try this

MATCH(p:Person{idNumber:111111})
MATCH(m:Person{idNumber:33333333})
MATCH path=(p)-[*2..4]-(m)
RETURN  p, m, relationships(path)

I am kinda lost on where we stand with your original query.