Get node by property value neo4j - neo4j

How can i get node by propery value? I mean something like that:
I'll tried
match (n) where has (n.name = 'Mark')
return n
But it's incorrect.
And also How can i find node with max property value. I have nodes with property "VIEWS" and i want see node with max views.

So close...
MATCH (n)
WHERE n.name = 'Mark'
RETURN n
It is better to include a node label if you have one that will serve to segregate your node from other nodes of different types. This way if you have an index on the name property and label combination you will get better search responsiveness. For instance, you can create the index...
CREATE INDEX ON :Person(name)
And then query with the Person label.
MATCH (n:Person)
WHERE n.name = 'Mark'
RETURN n
Or alternatively you can query this way...
MATCH (n:Person {name:'Mark'})
RETURN n
To find the person with the most views...
MATCH (n:Person)
RETURN n, n.views
ORDER BY n.views desc
LIMIT 1
To find the most views without the person...
MATCH (n:Person)
RETURN max(n.views)

Related

Get the nodes with specific labels in 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

Return a graph based on the number of relationships between nodes

I am experimenting with creating multiple relationships between nodes to represent the importance between two given nodes.
For example, I want to know what 'genre' of reading material is most important to Joe.
I want a way to match the Joe node to genre nodes only if there is some number or greater relationships between them.
So, if I want matches with 3 or more relationships, I should get a graph with Joe --> Fantasy
I know I can get this when both endpoints are defined:
MATCH (p:PERSON {name:'Joe'})-[r]->(g: GENRE {name:'Fantasy'})
RETURN count(r)
What I want is something like:
MATCH p = (p:PERSON {name:'Joe'})-[r]->()
WHERE *pair_relationship_count*(r) >= 3
RETURN p
This is my proposition:
MATCH path = (p:PERSON {name:'Joe'})-[r]->()
WITH collect(path) as paths, collect(r) as pair_count
WITH paths WHERE size(pair_count) >= 3
UNWIND paths as path
RETURN path
But maybe it is more efficient to have one relationship with an internal count property on one relationship for each couple of nodes.
First, I think you can achieve your goal using WITH clause:
MATCH path = (:PERSON {name:'Joe'})-[r]->(:GENRE {name:'Fantasy'})
WITH path, count(r) as count
WHERE count > 3
RETURN path
But using one relationship for each read "event" seems to be a bad approach. Maybe you should use an integer property in the relationship, then increment this property for each "read". This way you can do queries like:
MATCH path = (:PERSON {name:'Joe'})-[r]->(:GENRE {name:'Fantasy'})
WHERE r.count > 3
RETURN path
To get a collection of all READS paths for "Joe" that involve each genre that he has read at least 3 times:
MATCH p = (:PERSON {name:'Joe'})-[:READS]->(genre)
WITH genre, COLLECT(p) AS paths
WHERE SIZE(paths) >= 3
RETURN genre, paths;

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

cypher NOT IN query with Optional Match

NOT RELEVANT - SKIP TO Important Edit.
I have the following query:
MATCH (n)
WHERE (n:person) AND n.id in ['af97ab48544b'] // id is our system identifier
OPTIONAL MATCH (n)-[r:friend|connected|owner]-(m)
WHERE (m:person OR m:dog OR m:cat)
RETURN n,r,m
This query returns all the persons, dogs and cats that have a relationship with a specific person. I would like to turn it over to receive all the nodes & relationships that NOT includes in this query results.
If it was SQL it would be
select * from graph where id NOT IN (my_query)
I think that the OPTIONAL MATCH is the problematic part. I How can I do it?
Any advice?
Thanks.
-- Important Edit --
Hey guys, sorry for changing my question but my requirements has been changed. I need to get the entire graph (all nodes and relationships) connected and disconnected except specific nodes by ids. The following query is working but only for single id, in case of more ids it isn't working.
MATCH (n) WHERE (n:person)
OPTIONAL MATCH (n)-[r:friend|connected|owner]-(m) WHERE (m:person OR m:dog OR m:cat)
WITH n,r,m
MATCH (excludeNode) WHERE excludeNode.id IN ['af97ab48544b']
WITH n,r,m,excludeNode WHERE NOT n.id = excludeNode.id AND (NOT m.id = excludeNode.id OR m is null)
RETURN n,m,r
Alternatively I tried simpler query:
MATCH (n) WHERE (n:person) AND NOT n.id IN ['af97ab48544b'] return n
But this one does not returns the relationships (remember I need disconnected nodes also).
How can I get the entire graph exclude specific nodes? That includes nodes and relationships, connected nodes and disconnected as well.
try this:
match (n) where not n.id = 'id to remove' optional match (n)-[r]-(m)
where not n.id in ['id to remove'] and not m.id in ['id to remove']
return n,r,m
You've gotta switch the 'perspective' of your query... start by looping over every node, then prune the ones that connect to your person.
MATCH (bad:person) WHERE bad.id IN ['af97ab48544b']
WITH COLLECT(bad) AS bads
MATCH path = (n:person) - [r:friend|:connected|:owner] -> (m)
WHERE n._id = '' AND (m:person OR m:cat OR m:dog) AND NOT ANY(bad IN bads WHERE bad IN NODES(path))
RETURN path
That said, this is a problem much more suited to SQL than to a graph. Any time you have to loop over every node with a label, you're in relational territory, the graph will be less efficient.

neo4j how to use count(distinct()) over the nodes of path

I search the longest path of my graph and I want to count the number of distinct nodes of this longest path.
I want to use count(distinct())
I tried two queries.
First is
match p=(primero)-[:ResponseTo*]-(segundo)
with max(length(p)) as lengthPath
match p1=(primero)-[:ResponseTo*]-(segundo)
where length(p1) = lengthPath
return nodes(p1)
The query result is a graph with the path nodes.
But if I tried the query
match p=(primero)-[:ResponseTo*]-(segundo)
with max(length(p)) as lengthPath
match p1=(primero)-[:ResponseTo*]-(segundo)
where length(p1) = lengthPath
return count(distinct(primero))
The result is
count(distinct(primero))
2
How can I use count(distinct()) over the node primero.
Node Primero has a field called id.
You should bind at least one of those nodes, add a direction and also consider a path-limit otherwise this is an extremely expensive query.
match p=(primero)-[:ResponseTo*..30]-(segundo)
with p order by length(p) desc limit 1
unwind nodes(p) as n
return distinct n;

Resources