Reputation: 1601
I have a Document - [:Contains] -> Keyword relationship. I would like to obtain all the documents having a specified list of keywords. So far I managed to do this:
Match (d:document)-[:CONTAINS]->(k1:keyword {keyword:"key1"})
WITH d,k1
MATCH (d)-[CONTAINS]->(k2:keyword {keyword:"key2"})
return d, k1, k2
The above query returns all documents containing both "key1" and "key2" as keywords. The problem is that the query has to be modified depending on the number of keywords I am looking for. Is it possible to use a list as the search parameter and modify the list rather than the query itself?
Upvotes: 2
Views: 307
Reputation: 1601
In addition to what @cybersam suggested, this solution returns only those documents which match ALL the keywords.
MATCH (d:document)-[:CONTAINS]->(k:keyword)
WITH d,k, ["key1", "key2"] AS input
WHERE k.keyword IN input
WITH d, input, COUNT(k) AS cnt
WHERE cnt=size(input)
return d, cnt;
Upvotes: 0
Reputation: 66967
[UPDATED]
A query like this should work:
MATCH (d:document)-[:CONTAINS]->(k:keyword)
WHERE k.keyword IN {keywords}
RETURN d, COUNT(k) AS cnt
ORDER BY cnt DESC;
In this query, keywords
is assumed to be a collection of keyword strings passed as a parameter. I also assumed that CONTAINS
is a relationship type, hence I added the :
prefix.
For better performance, you can create an index on the keyword
property of the keyword
node label. (In practice, you should probably give the label and the property different names...).
CREATE INDEX ON :keyword(keyword);
After this, you may have to alter the original query to cajole the Cypher planner into using the index:
MATCH (d:document)-[CONTAINS]->(k:keyword)
USING INDEX k:keyword(keyword)
WHERE k.keyword IN {keywords}
RETURN d, COUNT(k) AS cnt
ORDER BY cnt DESC;
Upvotes: 3