Get the nodes with specific labels in neo4j - neo4j

I want to get all the nodes that have specific labels. My code:
match (n) where labels(n)=["Person","Actor","Old"] return n
While there are nodes that satisfy this property I do not get any results.

This is why:
Labels(n) returns an array of strings, but not necessarily in a specific order.
You can try this:
WHERE n:Person AND n:Actor AND n:Old
Or
WHERE ALL(l in [“Person”, “Actor”, “Old”] WHERE l IN labels(n) )

List does not match if the items are not in the same order/sequence. So first of all, list out all labels in your database so you can see how the labels are arranged.
match (n)
return distinct labels(n)
Then you will see which node will have those labels that you look for: ["Person","Actor","Old"].
If you are trying to find nodes where it contains all nodes in that list in any order then this query will work for you.
match (n)
where all(lbl in ["Person","Actor","Old"] where lbl in labels(n))
return n
if you like using APOC functions, here is the query
match (n)
where apoc.coll.isEqualCollection(["Person","Actor","Old"], labels(n))
return n

Related

How Many Nodes Are Involved in a Match

How can I know how many nodes and edges are involved in a MATCH? Is there another way besides Explain / Profile Match?
If you mean how many nodes are matched in a path, such as a variable-length path, then you can assign a path variable for this:
MATCH p = (k:Person {name:'Keanu Reeves'})-[*..8]-(t:Person {name:'Tom Hanks'})
WITH p LIMIT 1
RETURN p, length(p) as pathLength, length(p) + 1 as numberOfNodesInPath
You can also use nodes(p) and relationships(p) to get the collection of nodes and relationships that make up the path, and you can use size() on those collections to get their size.
There exists the COUNT() function of Cypher that allows you to count the number of elements. As for example in this query:
MATCH (n)
RETURN COUNT(n);
This query will count all nodes in your database.
You can find more information in the cypher manual, under the aggregating functions. Check it out.
The following Cypher snippet should return the number of distinct nodes and relationships found by any given MATCH clause. Just replace <your code here> with your MATCH pattern.
MATCH <your code here>
WITH COLLECT(NODES(p)) AS ns, SUM(SIZE(RELATIONSHIPS(p))) AS relCount
UNWIND ns AS nodeList
UNWIND nodeList AS node
RETURN COUNT(DISTINCT node) AS nodeCount, relCount;

Why doesn't labels(n) function return the correct count?

I want to count how many labels in my graph and execute the following:
match (n) return (count(labels(n)))
The count returned by this statement isn't the same as the count when I can see from the listed labels highlighted in different colors in the Browser. There are two more labels listed in the browser than the count returned by the function.
Why is that?
Your query is getting the label collection for each node, and then counting how many collections there are, which is the same as the number of nodes.
To get a count of the number of labels in the DB, you can use the APOC procedure apoc.meta.stats, which returns a variety of DB statistics. For your specific case, you can do this:
CALL apoc.meta.stats() YIELD labelCount
RETURN labelCount;
This cypher query will return a list of node labels and their counts:
match (n) return labels(n),count(n)
If you are seeking the count of a specific label, use
match (n:{your label}) return count(n)
If you want the count of the number of distinct labels:
match (n) with collect(distinct labels(n)) as NL return size(NL)

How to match nodes with exactly matching properties in Cypher?

In Cypher is there a way to match nodes exactly, i.e. match where the existing node contains only the properties queried for?
For example if we have the following nodes:
CREATE (n {field1: 'value1'})
CREATE (n {field1: 'value1', field2: 'value2'})
And match:
MATCH (n {field1: 'value1'}) RETURN (n)
This will return the both nodes. However, I want the second node to be excluded because it also contains field2 which is not in the set of queried properties
One way to do this is to use the properties function, i.e.
MATCH (n) WHERE properties(n) = {field1: 'value1'} RETURN (n)
But would be good to know whether there are other/better ways

Neo4j Aggregation Subtraction Nodes and properties

I'm starting with Neo4j and using graphs, and I'm trying to get the following:
I have to find the subtraction(difference) between the number of users (each user is a node) and the number of differents names they have. I have 16 nodes, and each one has his own name (name is one of the properties it has), but some of them have the same name (for example the node A has (Name:Amanda,City:Roma) and node B has (Name:Amanda, City:Paris), so I will have less name's count because some of them are repeated.
I have tried this:
match (n) with n, count(n) as c return sum(c)
That gives me the number of nodes. And then I tried this
match (n) with n, count(n) as nodeC with n, count( distinct n.Name) as
nameC return sum(nodeC) as sumN, sum(nameC) as sumC, sumN-sumC
But it doesn't work (I'm not sure if even i'm getting the names well, because when I try it, separated, it doesn't work neither).
I think this is what you are looking for:
MATCH (n)
RETURN COUNT(n) - COUNT(DISTINCT n.name) AS diff;

Cypher Optional Match

I have a graph in that contains two types of nodes (objects and pieces) and two types of links (similarTo and contains). Some pieces are made of the pieces.
I would like to extract the path to each piece starting from a set of objects.
MATCH (o:Object)
WITH o
OPTIONAL MATCH path = (p:Piece) <-[:contains*]- (o) -[:similarTo]- (:Object)
RETURN path
The above query only returns part of the pieces. In the returned graph, some objects do not directly connect to any pieces, the latter are not returned, although they actually do!
I can change the query to:
MATCH (o:Object) -[:contains*]-> (p:Piece)
OPTIONAL MATCH (o) –[:similarTo]- (:Object)
However, I did not manage to return the whole path for that query, which I need to return collection of nodes and links with:
WITH rels(path) as relations , nodes(path) as nodes
UNWIND relations as r unwind nodes as n
RETURN {nodes: collect(distinct n), links: collect(distinct {source: id(startNode(r)), target: id(endNode(r))})}
I'd be grateful to any recommendation.
Would something like this do the trick ?
I created a small graph representing objects and pieces here : http://console.neo4j.org/r/abztz4
Execute distinct queries with UNION ALL
Here you'll combine the two use cases in one set of paths :
MATCH (o:Object)
WITH o
OPTIONAL MATCH p=(o)-[:CONTAINS]->(piece)
RETURN p
UNION ALL
MATCH (o:Object)
WITH o
OPTIONAL MATCH p=(o)-[:SIMILAR_TO]-()-[:CONTAINS]->(piece)
RETURN p

Resources