Reputation: 2611
I have no idea of iterating on list in neo4j. Please some one suggest the idea for the below problem.
Example: I have some nodes in the graph. Then, I will give few(always varying, this is the user input) keywords to search for nodes which are common to this words. In my graph each word is a node.
Ex: Input: [Best sports car]
output: connected nodes for Best are [samsung,porshe,ambassdor,protein,puma]
connected nodes for sports are [cricket,racing,rugby,puma,porshe]
connected nodes for car are [porshe,ambassdor,benz,audi]
Common nodes to all words are : [porshe]
Result is : porshe
I don't have any idea of iterating each word and storing the match results. Please some one suggest any idea.
Upvotes: 1
Views: 692
Reputation: 20185
In order to test the following working query, I'll make some assumptions :
:Word
and the name
property.:Item
and a name property
.Item
nodes have an outgoing CONNECT
relationships to Word
nodesWhich will give the following graph :
The query is the following (in order to simulate the given words as parameters, I added a WITH containing the words list in the beginning of the query)
WITH ["car","best","sports"] as words
MATCH (n:Word)<-[:CONNECT]-(i:Item)
WHERE n.name IN words
WITH i, count(*) as c, words
WHERE c = size(words)
RETURN i
And will return only the porsche
Item node.
Logic explanation
The logic of the query, is that if a node matches all given words, there will be 3 patterns to it found in the first MATCH
, so the count(*)
will have a value of 3
here for the porsche
node.
This value is compared to the size
of the words
list.
More explanations
In the WITH
statement, there is two expressions : i
and count(*)
.
i
is not an aggregate function, so it will act as a grouping key.
count(*)
is an aggregate function and will run on the i
bucket, calculating the aggregate values.
For example, if you want to know how many words each Item
is matching you can simply do :
WITH ["car","best","sports"] as words
MATCH (n:Word)<-[:CONNECT]-(i:Item) WHERE n.name IN words
RETURN i.name, count(*)
Which will return this :
You can see that porsche
is matching 3 words, which is the size
of the given words
list, then you can simply compare the 3
from the count aggregation
to this size
.
In order to fully understand how aggregation works, you can refer to the manual : http://neo4j.com/docs/stable/query-aggregation.html
You can test the query here :
http://console.neo4j.org/r/e6bee0
If you pass the words as parameters, this will then be the corresponding query :
MATCH (n:Word)<-[:CONNECT]-(i:Item)
WHERE n.name IN {words}
WITH i, count(*) as c
WHERE c = size({words})
RETURN i
assuming {words} is the name of the given query parameter
Upvotes: 3
Reputation: 11216
Is something like this what you are after?
Start with a collection of words form the requested search.
Match each word against the graph.
Collect the connected words in a list.
with ['Best', 'sports', 'car'] as word_coll
unwind word_coll as word
match (:Word {name: word})--(conn_word:Word)
return word,collect(conn_word)
Upvotes: 1