Obi
Obi

Reputation: 3091

Convert cypher "WHERE IN" clause to Neo4JClient

How would I convert the following cyper query to Neo4JClient

MATCH (user:User),(interest:Interest)
WHERE interest.Id IN [2,4,9,17] AND user.Id = 46
CREATE user-[rel:INTERESTED_IN]->interest
RETURN rel

What I have done is

await graphClient.Cypher
             .Match("(interest:Interest)", "(user:User)")
             .Where((Interest interest) => interests.Contains(interest.Id))
             .AndWhere((User user) => user.Id == userData)
             .CreateUnique("user-[INTERESTED_IN]->interest")
            .ExecuteWithoutResultsAsync();

userData and interests are variables defined earlier in the method

My code throws the following exception

SyntaxException: Invalid input 't' (line 2, column 13)
"WHERE {p0}interest.Id
"
         ^

Upvotes: 0

Views: 1820

Answers (1)

ceej
ceej

Reputation: 1893

Assuming that userData is an int, I would suggest trying this

var userData = 46;
var interestIds = new[] { 2, 4, 9, 17 };

await _client.Cypher
    .Match("(interest:Interest), (user:User)")
    .Where((User user) => user.Id == userData)
    .AndWhere("interest.Id IN {interestIds}")
    .WithParams(new { interestIds })
    .ExecuteWithoutResultsAsync();

It might be easier to write the Cypher for the IN predicate as opposed to writing them into C# that then gets translated back. This is then parameterised, which according to the Neo4jClient documentation:

Cypher parameters are the safe way to inject dynamic information into queries. They avoid the risk of injection based attacks, and ensure that your values are accurately encoded.

They also significantly improve query plan caching on the Neo4j side, because the query text doesn't change so Neo4j doesn't have to recompile the plan on every hit.

Also note that this is not a direct translation of your original Cypher query since it does not return the created relationship(s).

Upvotes: 1

Related Questions