Running a case-insensitive cypher query - neo4j

Is it possible to run a case-insensitive cypher query on neo4j?
Try that: http://console.neo4j.org/
When I type into this:
start n=node(*)
match n-[]->m
where (m.name="Neo")
return m
it returns one row. But when I type into this:
start n=node(*)
match n-[]->m
where (m.name="neo")
return m
it does not return anything; because the name is saved as "Neo". Is there a simple way to run case-insensitive queries?

Yes, by using case insensitive regular expressions:
WHERE m.name =~ '(?i)neo'
https://neo4j.com/docs/cypher-manual/current/clauses/where/#case-insensitive-regular-expressions

Another way would be:
WHERE LOWER(m.Name) = LOWER("Neo")
And if you are using the Neo4j Client (.NET):
Client.Cypher.Match("(m:Entity)")
.Where("LOWER(m.Name) = LOWER({name})")
.WithParam("name", inputName)
.Return(m => m.As<Entity>())
.Results
.FirstOrDefault();

If anybody is looking on how to do this with a parameter, I managed to do it like this.
query = "{}{}{}".format('Match (n) WHERE n.pageName =~ "'"(?i)", name, '" RETURN n')
and "name" is the variable or your parameter

You can pass a parameter to the case insensitive regular expression like:
WHERE m.name =~'(?i)({param})

Related

neo4j: How do I query multiple properties for the same string?

I'm very new to neo4j and code generally. I'm trying to query multiple properties of my nodes for the same string, but don't want to have to type out my string in several times for each search.
For instance, right now my code is:
START b=node(*)
WHERE (b.name =~ '(?i).*edward.*' OR b.alias =~ '(?i).*edward.*')
RETURN b
Which means that I have to type out 'edward' twice for each search. Is there a way to avoid this?
You need the ANY function:
MATCH (b)
WHERE ANY(k IN ['name', 'alias'] WHERE toString(b[k]) =~ '(?i).*edward.*')
RETURN b
Define you regex in a parameter and use it like this:
:param regex: '(?i).edward.'
START b=node(*)
WHERE (b.name =~ $regex OR b.alias =~ $regex)
RETURN b

Writing a case-insensitive Cypher query to match the beginning of a string in Neo4j

I'm having trouble while trying to write a Cypher query that returns all the nodes which their name starts with a certain string. I also need this query to be case insensitive.
Cypher has built in functions for both cases, but I don't know how to combine them
Query for matching the beginning of a string:
MATCH (n) WHERE n.Name STARTS WITH 'Pet' RETURN n
Query for case-insensitive strings
MATCH (n) WHERE n.Name =~ '(?i)ANDR.*' RETURN n
Any help will be appreciated.
For a case insensitive comparison using the STARTS WITH string comparison operator you can use the toLower() string function to convert each side of the comparison to lower case. For example:
MATCH (n)
WHERE toLower(n.name) STARTS WITH toLower('Pet')
RETURN n

Passing parameter into Cypher query node_auto_index

I'm trying to pass a parameter into the Cypher query node_auto_index without any luck.
DecisionRepository.class:
#Query("START d=node:node_auto_index(':text') MATCH (d:Decision) RETURN d")
List<Decision> searchDecisions(String text);
Usage:
List<Decision> searchDecisions = decisionRepository.searchDecisions("name:aDbma~ OR name:mosyl~");
Is it possible and if so where I'm wrong ?
Use query parameters
START d=node:node_auto_index({myLuceneQuery}) RETURN d;
Then send "name:aDbma~ OR name:mosyl~" as {myLuceneQuery}

Cypher query and Ruby on Rails

I have a Cypher query like this:
start n=node(*) match n-[:has_comments]->(m) return n,m;
which runs ok.
How can I run this from RoR?
When using Postgres and ActiveModel, in the controller I was able to do use something like this.
#query = "SELECT * FROM <table> WHERE <condition>;"
#result = <ClassName>.connection.execute(#query)
And after that I processed #result any way I wanted.
You can use Neo4j::Session.current.query to build general Cypher queries. Don't use START n=node anymore, that syntax isn't valid in future versions, so you should use MATCH (n) WHERE ID(n) = instead.
query = "MATCH (n)-[:has_comments]->(m) WHERE ID(n) = #{id} RETURN n, m"
result = Neo4j::Session.current.query(query).to_a
That'll give you an array of structs, with your results accessible by calling the n and m methods, respectively. I don't suggest you do it this way at all. As an alternative, you can do this:
result = Neo4j::Session.current.query.match("(n)-[:has_comments]->(m)").where("ID(n) = {id}").params(id: id).return(:n, :m)
You'll access the data the same way: n and m methods.
I don't recommend you do that, either. You're using Rails and ActiveNode, so you should have models and be able to do n_node.as(:n).comments(:m).pluck(:n, :m).

Replace regular expressions in cypher

I can search for regular expressions in cypher
MATCH (n:model) WHERE n.name =~ '.*&.*;.*' RETURN n.name
but can I also replace them? I would like to write something like
MATCH (n:model) RETURN replace(n.name, ~'&.*;', '_');
There is a replace function in cypher, but it does not replace regexps, just simple strings.
Maybe a feature request for replaceRegex could be done?
An workaround would be to do this programatically, after you return the names (if you use call cypher queries from another application).

Resources