Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

neo4j cypher - how to find all nodes that have a relationship to list of nodes

Tags:

neo4j

I have nodes- named "options". "Users" choose these options. I need a chpher query that works like this:

retrieve users who had chosen all the options those are given as a list.

MATCH (option:Option)<-[:CHOSE]-(user:User) WHERE  option.Key IN ['1','2','2'] Return user

This query gives me users who chose option(1), option(2) and option(3) and also gives me the user who only chose option(2).

What I need is only the users who chose all of them -option(1), option(2) and option(3).

like image 727
hisarkaya Avatar asked Jan 13 '14 13:01

hisarkaya


People also ask

How do I return all nodes and relationships in Neo4j?

When you want to return all nodes, relationships and paths found in a query, you can use the * symbol. This returns the two nodes, the relationship and the path used in the query.

What is the syntax for getting all the nodes under specific label in Neo4j?

If you want to get the labels of a specify node, then use labels(node) ; If you only want to get all node labels in neo4j, then use this function instead: call db. labels; , never ever use this query: MATCH n RETURN DISTINCT LABELS(n) . It will do a full table scan, which is very very slow..

Which query is used to return the count of the relationship for a node?

Using count(*) to return the number of nodes. The function count(*) can be used to return the number of nodes; for example, the number of nodes connected to some node n . The labels and age property of the start node n and the number of nodes related to n are returned.

What are nodes and relationships in Neo4j?

The Neo4j property graph database model consists of: Nodes describe entities (discrete objects) of a domain. Nodes can have zero or more labels to define (classify) what kind of nodes they are. Relationships describes a connection between a source node and a target node.


1 Answers

For an all cypher solution (don't know if it's better than Chris' answer, you'll have to test and compare) you can collect the option.Key for each user and filter out those who don't have a option.Key for each value in your list

MATCH (u:User)-[:CHOSE]->(opt:Option)
WITH u, collect(opt.Key) as optKeys
WHERE ALL (v IN {values} WHERE v IN optKeys)
RETURN u

or match all the options whose keys are in your list and the users that chose them, collect those options per user and compare the size of the option collection to the size of your list (if you don't give duplicates in your list the user with an option collection of equal size has chosen all the options)

MATCH (u:User)-[:CHOSE]->(opt:Option)
WHERE opt.Key IN {values}
WITH u, collect(opt) as opts
WHERE length(opts) = length({values}) // assuming {values} don't have duplicates
RETURN u

Either should limit results to users connected with all the options whose key values are specified in {values} and you can vary the length of the collection parameter without changing the query.

like image 65
jjaderberg Avatar answered Oct 24 '22 18:10

jjaderberg