Contains text in matched to list

Hello Everyone,

I am attempting to search nodes for a property that is in a list. See the following.

WITH ["Creator", "Juniors", "Technic"] AS subs
MATCH (t:Toy)
WHERE t.ProductName contains in subs
return t

I know the code is wrong, but it gives you an idea of what I want to achieve. So I have a field named t.Productname and in that property the string could look as follows: "Creator 31003 Red Rotors " or "Technic 42020: Twin-Rotor Helicopter".

What I want to do is search for all the product names that contain any of the words from the literal list and with matched pattern I will set the property brand to Lego.

I can't seem to get my head around how to use the literal list to do the comparison with. I was already able to simply do WHERE t.ProductName CONTAINS "Creator"
That worked perfectly, but I don't want to match one by one, so I thought of FOREACH, but can't find any good explanation on how to mix those two.

Thank in advance,
Jeffrey

Hello @tideon :slight_smile:

You should have a look at predicate functions:

WITH ["Creator", "Juniors", "Technic"] AS subs
MATCH (t:Toy)
WHERE any(word IN subs WHERE t.ProductName CONTAINS word)
RETURN t

Regards,
Cobra

1 Like

Thank you Cobra.

it always amazes me when you get a solution. I was in the ball park, as they say, so close, but yet so far. I will have a look at predicates.

Greetings,
Jeffrey

Hello Cobra,

I am having a bit of a problem getting my head around what a predicate is when it comes to cypher, Python or any other programming language. On youtube you see the meaning in the gramatical form, but not so much of what it means in computer science.

Do you happen to have a link that can make it clear?

Found this:


Thanks in advance,
Jeffrey

A predicate asks a question where the answer is true or false or, said another way, yes or no.

The WHERE clause allows you to create your own predicate, so in your example, the aim is to return all "toys" that have a sub string in their product name. So you want to get all products that make the WHERE clause true. The solution I gave you will check if at least one product name have one sub string from the subs list.

I hope it's more clear, you can see the predicate like a condition if you prefer:
"if there is at least a sub string in my product name then I return it"

1 Like

Thank you for that explanation.

1 Like

Hello Cobra,

One thing that I always think about is how the query is executed. So does Cypher loop through the where predicate with the ant then move on, or does it go through the entire query from top to bottom until it has no more?

I have a feeling it will loop through the expression each time then move on, being that for instance count need to deal with all at once, but it could also have a way of adding one each loop.

Very curious as to what you know of this.

Hello Cobra,

I have been starring at the code for some time, but I am still wordering what inspired you to use two where's like that. I understand it works, but I wouldn't have seen that at this stage in my learning of cypher.

What is the special function of the outer where? Is it that the any() function needs to give it off to something such as a where?

Thanks in advance,
Jeffrey

The answer of your first question is here: https://neo4j.com/docs/cypher-manual/current/clauses/match/#match-introduction

To be honest, it's just practice, even me at the beginning, I was not aware of these functions. So now, I know that these functions can solve this type of problems. Yeah any() must be used in a WHERE clause and you have always a WHERE clause in the any() function.

Hahahahaha, that is crazy!!! And the fact that they don't state that in the manual.

i really am struggling with the manual. it is written so abstract, and often have a minimal in information and often misses adding these very important part. I am going to see if we as a community can add to the manual, because often I see better explanations in the forum. An so many people are asking the exact questions that are missing from the manual.

You know what the thing is about learning cypher. You can't do the normal set of rules for learning. In that I mean you first learn the basics and get into functions later, you quite quickly have to learn the function and APOC.

You should see APOC like chapter 2 of Cypher, if you can't do something in classic Cypher, you maybe able to do it with APOC :slight_smile:

Hahahahaha, was forced into APOC to use the load JSON, then I was immediately back out. That is theonly function I use from APOC.

The weirdness of SQL and Cypher is that these languages are declarative. Almost all other computer languages are procedural (or functional), which is more natural way of thinking, i.e. like creating a recipe for a cook to follow. I think of declarative languages like setting up some billiard balls and having a good player run the table.

Declarative languages requires a different way of thinking which takes a while to get used to. You need to practice and learn from trial and error. I recommend trying out lots of examples in the training materials.

Hello Clem,

The funny thing is that I got my head around it quite quickly, but the documentation on how to use the words are what are my biggest issue right now. Often in the books I read I see information that simply not in the online manual, or at times on the forum there are detal that are so important to using a function, but yet isn't in the manual.

Cobra above mentioned such an important detail about using any(), and when you read the manual, that info is no where to be found.
Here is what he said:

To be honest, it's just practice, even me at the beginning, I was not aware of these functions. So now, I know that these functions can solve this type of problems. Yeah any() must be used in a WHERE clause and you have always a WHERE clause in the any() function.

I am learning Python right now also, so to use it with Cyper.
You know, the any() function looks like a comprehension list from Python.

Yeah it uses the same principle, there is also classic list of comprehension in Cypher.

Can you give me a link? I didn't know about this. It really help to speed up learning this stuff when you come across similar techniques.

Are you speaking about this?

2 Likes

Hi,

I think that performance wise and ease of use, it is way better to use Full Text Search which is using the embedded Lucene engine.
Basically you create an index based on the node's label and properties and then call the search with a Lucene query.
In your case it would be very simple:

CALL db.index.fulltext.queryNodes('searchProductName', '*Creator* *Junior* *Technic*') 
YIELD node AS t 
RETURN t

Read more about full text search in the Neo4j docs.

Ugh, this seems much more elegant than what I was using to accomplish this. I'm curious as to the performance.

WITH { list:["Creator", "Juniors", "Technic"]} AS nody
WITH nody where REDUCE(string = '', n IN nody.list | string + " | " + n) CONTAINS "Juniors"
RETURN nody