Jeff H
Jeff H

Reputation: 155

Neo4jClient - How to check if property exists

I'm having trouble converting the following Cypher query to the Neo4jClient syntax.

MATCH n WHERE NOT (HAS (n.User)) OR n.User = "username" RETURN n

This is what I currently have with the addition of some relationship logic and the omission of the HAS logic

var results = Client.Cypher
               .OptionalMatch("(result)-[connection:Connection]-(result2)")
               .Where((Result result) => result.User == username)
               .Return((result, connection, result2) => new Neo4jResultSingle()
               {
                   SearchedNode = result.As<Node<Result>>(),
                   RelationshipConnection = connection.As<RelationshipInstance<Connection>>(),
                   Relationship = connection.As<RelationshipInstance<ConnectionRelationship>>(),
                   RelationshipedNode = result2.As<Node<Result>>()
               }).Results.ToList();

Upvotes: 10

Views: 15311

Answers (3)

Thennan
Thennan

Reputation: 898

In Neo4j 4.3,

The exists() function has been deprecated for property existence checking and has been superseded by IS NOT NULL.

So please use

MATCH (n) 
WHERE n.User IS NOT NULL 
RETURN n

OR

MATCH (n) 
WHERE n.User IS NULL 
RETURN n

In your code specifically,

var results = Client.Cypher
       .Match("(result)-[connection:Connection]-(result2)")
       .Where("WHERE n.User IS NULL OR n.User = {username}")
       .WithParams(new { username = username })
       .Return((result, connection, result2) => new Neo4jResultSingle()
       {
           SearchedNode = result.As<Node<Result>>(),
           RelationshipConnection = connection.As<RelationshipInstance<Connection>>(),
           Relationship = connection.As<RelationshipInstance<ConnectionRelationship>>(),
           RelationshipedNode = result2.As<Node<Result>>()
       })
       .Results
       .ToList();

Upvotes: 12

vladkras
vladkras

Reputation: 17227

HAS was superseded by EXISTS()

From the latest docs: Property existence checking

MATCH (n) WHERE EXISTS(n.User) RETURN n

for opposite match add NOT before

MATCH (n) WHERE NOT EXISTS(n.User) RETURN n

Upvotes: 11

ceej
ceej

Reputation: 1893

Looking at a combination of your original query and your C# maybe the following might help?

var results = Client.Cypher
           .Match("(result)-[connection:Connection]-(result2)")
           .Where("WHERE NOT HAS(n.User) OR n.User = {username}")
           .WithParams(new { username = username })
           .Return((result, connection, result2) => new Neo4jResultSingle()
           {
               SearchedNode = result.As<Node<Result>>(),
               RelationshipConnection = connection.As<RelationshipInstance<Connection>>(),
               Relationship = connection.As<RelationshipInstance<ConnectionRelationship>>(),
               RelationshipedNode = result2.As<Node<Result>>()
           })
           .Results
           .ToList();

This rewrites your WHERE clause to include both the HAS and username logic, whilst parameterising it to cache the query plan and protect against injection.

Upvotes: 2

Related Questions