Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-06-2020 01:58 AM
Hello,
I have a very beginner question but I didn't find any solution in tutorials and forum.
I would like to search a pattern in a list of strings. Below the 'n.name' is only a string and I would like to do the same operation but on a list.
MATCH (n:Person)
WHERE n.name =~ '(?i)AND.*'
RETURN n.name, n.age
I see how to find a exact value in list with (but not with a matching pattern):
MATCH (n:Person)
WHERE "VALUE" IN n.name
RETURN n.name, n.age
Thank you very much and sorry if the question was already asked.
William
Solved! Go to Solution.
03-09-2020 04:35 PM
When you have a node with a list property, you can use list predicate functions to test if any, all, or none of the elements of the list meet a predicate.
So in your case, something like this may work:
MATCH (n:Person)
WHERE any(name in n.name WHERE name =~ '(?i)AND.*')
RETURN n.name, n.age
Note that this approach will not leverage indexes. If you do need to leverage indexes like this, you may have to consider restructuring your data model with new kinds of nodes, such as :Alias nodes attached to a :Person, each one with a name (that is indexed), and have your query do an index lookup on the alias name using a lookup that will utilize the index, then MATCH to the :Person nodes for that alias.
03-06-2020 03:04 AM
Well you can collect that attributes you want in a list like this:
MATCH (n:Person)
with collect(n.names) as names
UNWIND names a n
where n.name =~ <YOUR LOGIC HERE>
This will return you a list a names that you can then UNWIND or loop through and perform your operations on them.
03-06-2020 06:30 AM
Thank you very much for the help.
However, when I try this to my dataset, i got an error that let me think I cannot use WHERE after UNWIND.
Also these two queries give the same result that I was not expecting
QUERY 1
MATCH (n:Person)
with collect(n.names) as names
UNWIND names as n
return n
QUERY 2
MATCH (n:Person)
return n.names
Screen of these two examples.
Query without unwind
I was expecting 'collect' to unroll all the element and put it in a simple list whereas this is still a list of list of string.
03-06-2020 06:48 AM
You can interact with the list after each collect. So you can use WHERE for sure. There are some other APOC methods you can use as well.
03-06-2020 10:42 PM
Logic for Manipulation in List
MATCH (n:Person)
with collect( distinct n) as names
with [name in names where name.name=~'B' or name.name=~'A'] as name
return name
03-09-2020 04:35 PM
When you have a node with a list property, you can use list predicate functions to test if any, all, or none of the elements of the list meet a predicate.
So in your case, something like this may work:
MATCH (n:Person)
WHERE any(name in n.name WHERE name =~ '(?i)AND.*')
RETURN n.name, n.age
Note that this approach will not leverage indexes. If you do need to leverage indexes like this, you may have to consider restructuring your data model with new kinds of nodes, such as :Alias nodes attached to a :Person, each one with a name (that is indexed), and have your query do an index lookup on the alias name using a lookup that will utilize the index, then MATCH to the :Person nodes for that alias.
03-11-2020 10:57 AM
Thanks very much for the queries. I will try them when my server is back and will let you know if it works.
All the sessions of the conference are now available online