Complex filter with big graph very slow

I work on big graphs and the ability to filter over them.

I have data of type Domain which point towards a Subdomain then towards the ipv4 and finally the ports, then service etc ..


The goal is that starting from the domain, I am filtering on the branches of the graph having, for example, IPv4 and port 80.


Today, the solution we use is:

MATCH (e:Entity)-[:HAS_ASSET *0..]->(a:Asset:Ipv4)
WHERE id(e)=**
AND EXISTS { MATCH (b0)-[:HAS_ASSET *0..]->(a)-[:HAS_ASSET *0..]->(c0)
WHERE (b0:Service AND (b0.value='220 microsoft ftp shttpervice'))
OR (c0:Service AND (c0.value='http')) }

OPTIONAL MATCH (b:Asset)-[:HAS_ASSET *0..]->(a:Asset)

OPTIONAL MATCH (a:Asset)-[:HAS_ASSET *0..]->(c:Asset)

The first match is used to match the ipv4 from which we will search the branches. And then making us a match to go up and down to get everything back.
These are queries generated by our api, hence the need to search before or after the services, even if we all know that the services are after the ipv4. (We have several hundred different types, so impossible to make special cases)

Two things :

  • => It is the right way to do that ?

  • => If yes, the problem is that the request is long over large perimeters, and that in the case of a Domain pointing to, say 10,000 subdomains, which all point to the same ip, the second match in the exist :

MATCH (b0)-[:HAS_ASSET *0..]->(a)-[:HAS_ASSET *0..]->(c0)
WHERE (b0:Service AND (b0.value='220 microsoft ftp shttpervice'))
OR (c0:Service AND (c0.value='http')) 

will use as many as finded a, that subdomain point on, even if they have the same value.
The solution for this problem is to separate the 2 matchs like :

MATCH (e:Entity)-[:HAS_ASSET *0..3]->(a:Asset:Ipv4)
WHERE id(e)=**
with distinct a as a

match (a) where
EXISTS { MATCH (b0)-[:HAS_ASSET *0..]->(a)-[:HAS_ASSET *0..]->(c0)
WHERE (b0:Service AND (b0.value='220 microsoft ftp shttpervice'))
OR (c0:Service AND (c0.value='http')) }

It's faster, but very dirty. Have you any advice ?