Search code examples
neo4jneo4jclient

Neo4j IN clause case-insensitive


I created a node in neo4j db with this command:

CREATE (n:Person {Names: 'A', 'B', 'C'}) RETURN n;
CREATE (n:Person {Names: 'D'}) RETURN n;

Now, I want to make a query to retrieve a person has one of the name in a specific list.

I have this list : ['a', 'c'] -> It will return the 1st person

I know I have to use IN clause for this query, but I don't know how to achieve it.

I would like to write the command in Neo4j DB Browser and Neo4j Client .Net.

Can anyone help me please ?

Thank you.


Solution

  • 1) You have an incorrect query to add nodes. It should be like this:

    CREATE (n:Person {Names: ['A', 'B', 'C']}) RETURN n;
    CREATE (n:Person {Names: ['D']}) RETURN n;
    

    2) To search for occurrences of at least one value from the list, you can use the predicate ANY:

    WITH ['a', 'D'] as Names
    MATCH (P:Person)
    WITH P, extract(name IN P.Names | LOWER(name)) as lowNames
      WHERE ANY(n IN Names WHERE LOWER(n) IN lowNames)
    RETURN P
    

    Update. It is not excluded that it is better way in the spirit of "graph" is change the model. If we assume that the names can be repeated with different persons, then for each name it is necessary to add a node, and add a relationship with the person:

    enter image description here

    Create query:

    MERGE (P1:Person {id:'P1'}) 
    MERGE (P2:Person {id:'P2'}) 
    MERGE (P3:Person {id:'P3'}) 
    MERGE (N1:Name {name:'A'}) 
    MERGE (N2:Name {name:'B'}) 
    MERGE (N3:Name {name:'C'}) 
    MERGE (N4:Name {name:'D'}) 
    MERGE (P1)-[:has_name]->(N1) 
    MERGE (P1)-[:has_name]->(N2) 
    MERGE (P1)-[:has_name]->(N3) 
    MERGE (P2)-[:has_name]->(N4) 
    MERGE (P3)-[:has_name]->(N1) 
    MERGE (P1)-[:has_name]->(N4)`
    

    And a query to search persons:

    // Find the desired names
    WITH ['a', 'D'] as Names
    WITH extract(name IN Names | LOWER(name)) as lowerNames
    MATCH (N:Name) WHERE LOWER(N.name) IN lowerNames
    // For each name, we find person
    WITH N
      MATCH (P:Person)-[:has_name]->(N)
    RETURN collect(distinct P)