0
votes

I'm trying to return content nodes based on terms that the user has selected. The following is my cypher query as it is:

    MATCH 
        (content:content)-[:TAGGED_WITH]-(term:term)
    WHERE
        term.UUID IN {includedTerms}
        AND NOT term.UUID IN {excludedTerms}
    RETURN DISTINCT content.whatever

Where {includedTerms} is an array of UUIDs for the terms to be included.

The problem is that it is returning content connected to any of the included term nodes rather than content that is connected to each of the included term nodes.

I realize that the query is returning exactly what I'm telling it to. The question is how can I specify that the content must be tagged with every (and not any) of the term nodes that the user has selected?

Thanks a lot- let me know if there is any needed clarification.

2

2 Answers

1
votes

Perhaps using WITH could help:

MATCH 
    (content:content)-[:TAGGED_WITH]-(term:term)
WHERE
    term.UUID IN {includedTerms}
    AND NOT term.UUID IN {excludedTerms}
WITH content, count(*) as connectedTerms
WHERE connectedTerms = {_included_terms_size_}
RETURN DISTINCT content.whatever
1
votes

I cant understand the use of NOT term.UUID IN {excludedTerms} but you can edit below query as per your needs.

The below query will use only the term nodes which will have UUIDs attributes from the desired includedTerms set.

MATCH (term:term) 
WHERE term.UUID IN [includedTerms] 
WITH collect(term) AS ms 
MATCH (content:content)-[r:TAGGED_WITH]->(x) 
WHERE x IN ms 
WITH content, count(r) AS rs,ms 
WITH collect(content) AS ns, collect(rs) AS rss, length(ms) AS mss 
RETURN [t IN range(0,length(ns)-1) 
  WHERE rss[t]=mss | ns[t]] AS result