65

It appears that LIKE is not supported in Cypher queries.

Is there any other construct that would perform the same task?

For instance:

start n = node(*) where n.Name LIKE('%SUBSTRING%') return n.Name, n;
johnc
  • 39,385
  • 37
  • 101
  • 139
  • 1
    The refcard is a really handy thing to bookmark: http://neo4j.com/docs/cypher-refcard/current/ It lists all supported string matching operators for example. – F Lekschas May 04 '17 at 19:42

4 Answers4

84

using regular expressions: http://neo4j.com/docs/developer-manual/current/#query-where-regex

start n = node(*) where n.Name =~ '.*SUBSTRING.*' return n.Name, n;
Magnus
  • 7,952
  • 2
  • 26
  • 52
ulkas
  • 5,748
  • 5
  • 33
  • 47
  • 3
    I was worried regex's may be the answer. Groans ;) Still, it makes it more powerful than a simple LIKE – johnc Dec 12 '12 at 18:34
  • 2
    yes, i'm also concern about regexp but it is the direct way now. but you can still use an lucene index like this : `start n=node:your_index('property:*SUBSTRING*') return n.name, n;` – ulkas Dec 12 '12 at 19:10
  • 4
    and please use parameters instead of literal values: `start n = node(*) where n.Name =~ {like} return n.Name, n;` params: {"like":".*SUBSTRING.*"}, also node(*) as start clause hints at a non-graph use-case, then rather use ulkas' index lookup suggestion – Michael Hunger Dec 19 '12 at 18:25
  • 2
    Seems that it's not working with ".*SUBSTRING.*" but only with "^.*SUBSTRING.*$" – clement May 26 '15 at 14:24
  • @MichaelHunger So in an SDN repository having the .* in the argument instead of in the query, forces us to concatenate them in the service layer if we can't fit them in @Query("MATCH (m:Neo4JManufacturer) where LOWER(m.name) =~ LOWER('{searchTerm}') RETURN m ORDER BY m.name") public List search(@Param("searchTerm") String searchTerm); Is that a correct assumption ? – Stephane Sep 11 '15 at 08:40
  • I was hoping to do a @Query("MATCH (m:Neo4JManufacturer) where LOWER(m.name) =~ LOWER('.*{searchTerm}.*') RETURN m ORDER BY m.name") public List search(@Param("searchTerm") String searchTerm); but it gives me: Illegal repetition near index 1 .*{searchterm}.* – Stephane Sep 11 '15 at 08:47
  • I got it working with a repository like LOWER(m.name) =~ LOWER({searchTerm}) and a service with searchTerm = ".*" + searchTerm + ".*"; – Stephane Sep 11 '15 at 09:19
29

As of version 2.0, the preferred syntax uses MATCH.

e.g.

MATCH (n) where n.Name =~ '.*SUBSTRING.*' return n.Name, n;
Ryan Walls
  • 6,962
  • 1
  • 39
  • 42
28

No Regexps needed:

start n = node(*) where n.Name contains "substring" return n.Name, n;

Go to the cypher refcard and scroll down to the Predicates section. You will find this and other useful stuff.

Want case-insensitive? Convert to lower case:

start n = node(*) where lower(n.Name) contains lower("substring") return n.Name, n;
  • sadly, it's case sensitive and there's no case insensitive version. ugh! – ekkis May 28 '17 at 06:41
  • 2
    yes, that will work, as will `=~ '(?i)substring'` but it doesn't perform well. the lower() prevents index usage so on big data it will just hang. I have an open feature request here: https://github.com/neo4j/neo4j/issues/9450 – ekkis Jun 02 '17 at 23:42
  • The function lower() is no longer supported. Please use toLower() instead. – Samuel Adeshina Dec 05 '22 at 09:28
20

If you want to make it case insensitive

MATCH (n) WHERE n.name =~ '(?i).*SUBSTRING.*' RETURN n;
arikan
  • 1,023
  • 8
  • 6