Search code examples
neo4jcypher

How to write or with not query in neo4j


I want to perform this query in neo4j but i'm not getting proper.

NOT((service provid_by Adani Transmission Limited AND service address_in Formosa) OR service depen_on Video interview data)

Cypher query

MATCH (node:service )-[provid_by]->(dst:provider)
WITH DISTINCT node, COLLECT(DISTINCT TOLOWER(dst.name)) AS names
WHERE NONE(name IN names WHERE name IN ["adani transmission limited"]) OR size(names) = 0
WITH DISTINCT node
RETURN DISTINCT node
UNION
MATCH (node:service )-[address_in]->(dst:Address)
WITH DISTINCT node, COLLECT(DISTINCT TOLOWER(dst.name)) AS names
WHERE NONE(name IN names WHERE name IN ["formosa"]) OR size(names) = 0
WITH DISTINCT node
MATCH (node:service)-[depen_on]->(dst:res)
WITH DISTINCT node, COLLECT(DISTINCT TOLOWER(dst.name)) AS names
WHERE NONE(name IN names WHERE name IN ["video interview data"]) OR size(names) = 0
WITH DISTINCT node
WITH DISTINCT node
ORDER BY node.createdAt DESC
RETURN DISTINCT node
UNION
MATCH (node:service) WHERE NOT (node)-[:provid_by]->(:Participant)
WITH DISTINCT node
RETURN DISTINCT node
UNION
MATCH (node:service)
WHERE NOT (node)-[:address_in]->(:Address)
WITH DISTINCT node
RETURN DISTINCT node
UNION
MATCH (node:service)
WHERE NOT (node)-[:depen_on]->(:res)
WITH DISTINCT node
RETURN DISTINCT node

Solution

    1. The first 3 MATCH clauses did not use a colon in front of the relationship type. For example, [provid_by] should be [:provid_by]. This may or may not have caused a difference in the results, but it would have slowed down the query.

    2. Another issue, and it is a big one, is that UNION can only add rows to the ultimate result. It cannot filter out any rows provided by other UNION terms.

    3. Also, it is not clear why you have the last 3 UNIONs. They would only add a lot of nodes that do not pass your stated criteria.

    This simpler query may be sufficient:

    MATCH (node:service)
    WHERE
     (
       NONE(n IN [(node)-[:provid_by]->(dst:provider)|dst.name] WHERE n =~ "(?i)Adani Transmission Limited") OR
       NONE(n IN [(node)-[:address_in]->(dst:Address)|dst.name] WHERE n =~ "(?i)Formosa")
     ) AND
     NONE(n IN [(node)-[:depen_on]->(dst:res)|dst.name] WHERE n =~ "(?i)Video interview data")
    RETURN node
    ORDER BY node.createdAt DESC