How to return distinct node properties? - neo4j

MATCH (p:car)-[r]->(n:brand) where n.brandname = 'Nissan' RETURN p.sku_id
This query will return all 'sku_id' for the query. How can I only return unique 'sku_id' only for the same query?

You can use DISTINCT if many Ids are the same :
MATCH (p:car)-[r]->(n:brand)
WHERE n.brandname = 'Nissan'
RETURN DISTINCT p.sku_id
Maybe you have to be more precise :
MATCH (p:car {model:"Micra"})-[r]->(n:brand {brandname:"Nissan"})
RETURN DISTINCT p.sku_id

Related

Neo4j match using a list

i have a node like this: (:a{name:'',lname:'',listNumb:[1,3,9]})
i want to select when 1 is in the array
this is what itried to do
match (:a ) where a.listNumb=1 return a ; or match (:a {listNumb=1})
You can use IN to check if a value is present in the array/list.
MATCH (n:a)
WHERE 1 IN n.listNumb
RETURN n;

How to query with two conditions in Neo4j

I am new with Neo4j and I am stucked trying to get a query with two conditions, where I want to get all the "Autors" related to "Pixar" and "Fox". So far I have tried the following two ways:
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora {Nombre: "Pixar"}),
and
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora {Nombre: "Fox"}),
return a,p
and
MATCH (a:Autor)- [:AUTOR_DE]-> (t:Título) -[:PRODUCIDO_POR] ->( p:Productora)
WHERE ( (p:Productora) = "Fox" OR (p:Productora) = "Pixar")
return a,p
Thanks in advance
Assuming that a Productora node stores its name in a name property, and that every Productora node has a unique name, this should work:
MATCH (a:Autor)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(p:Productora)
WHERE p.name = "Fox" OR p.name = "Pixar"
WITH a, COLLECT(DISTINCT p) AS ps
WHERE SIZE(ps) = 2
return a, ps
And this should also work:
MATCH (fox:Productora), (pixar:Productora), (a:Autor)
WHERE fox.name = "Fox" AND pixar.name = "Pixar" AND
(a)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(fox) AND
(a)-[:AUTOR_DE]->(:Título)-[:PRODUCIDO_POR]->(pixar)
return a, fox, pixar

Match nodes with two different values in same property Neo4j

I have this kind of graph:
I want to retrieve all Products that have pending or open requests. This is how Im trying
MATCH (s:ServiceRequest {srStatus: "Open"} OR {srStatus: "Pending"}) -[:FOR]->(p:Product) RETURN p
But this does not work. How can I do that?
This should work:
MATCH (s:ServiceRequest)-[:FOR]->(p:Product)
WHERE s.srStatus IN ["Open", "Pending"]
RETURN p;
and so should this:
MATCH (s:ServiceRequest)-[:FOR]->(p:Product)
WHERE s.srStatus = "Open" OR s.srStatus = "Pending"
RETURN p;

How to find all oldest sibling in all families

If I have a lot of families represented like:
(parent:Person)<-[:CHILD_OF]-(child:Person {age:19})
then how would a query look like that finds the oldest child of all families?
I have the following suggestion, but this only returns 1 node:
match (parent:Person)<--(child:Person) return child order by child.age desc limit 1
Probably can be optimized, here's a quick go at it-
match (c:Person)-[:CHILD_OF]->(p)
with p, max(c.age) as maxAge, collect(c) as children
return p,filter (x in children where x.age=maxAge)
match (parent:Person)<--(child:Person) with parent, max(child.age) as maxAge
Match (parent)<--(child:Person) where child.age = maxAge
return *
It might return several childs if they have maximum same age, if you want to return one, you should use one more creteria like
max(id(child))
and you will have
Match (parent:Person)<--(child:Person) with parent, max(child.age) as maxAge
Match (parent)<--(child:Person) where child.age = maxAge with parent, max(id(child)) as maxId
Match (parent)<--(child:Person) where id(child) = maxId return *

How to avoid duplications return distinct nodes and the relation ship using neo4j

I would like to return for a given node-id related nodes and their relationships props
For example:
-> defines a bi direction relationship with property timestamp
1234->777
777->1234
1234->999
999->1234
1234->888
888->1234
1234,777,888,999 are node-ids
When I execute this:
final PreparedStatement ps = conn.prepareStatement("start a = node(1234) match (a)-[k:nearby*]->(b) where a<>b return DISTINCT b, k");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Map result = (Map<String, Object>) rs.getObject("b");
System.out.println(result.toString());
}
} catch (SQLException e) {
e.printStackTrace();
logger.error("Error returning userId=" + userIdInput, e);
}
return null;
}
I get:
{userId=777}
{userId=999}
{userId=888}
{userId=888}
{userId=999}
{userId=999}
{userId=777}
{userId=888}
{userId=888}
{userId=777}
{userId=888}
{userId=777}
{userId=999}
{userId=999}
{userId=777}
How I do get distinct results only (777,888,999)
How to retrieve the relationship props of 1234 to the dest node? I expect to get the timestamp prop which defined on each relationship
Thank you,
ray.
I'm not sure what language you're using so I'll focus on the Cypher. Firstly I would replace the START query with a MATCH with a WHERE on ID(a):
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = 1234 AND a<>b
RETURN DISTINCT b, k
Secondly I'm pretty sure you don't need the a<>b because Cypher paths won't loop back on the same nodes:
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = 1234
RETURN DISTINCT b, k
Lastly, and to your question, I suspect the reason that you're getting duplicates is because you have multiple relationships. If so you can return the result node and an array of the relationships like so:
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = 1234
RETURN collect(b), k
That should return you node/relationship objects (with properties on both). Depending on your language/library you might get Maps or you might get objects wrapping the data
If your library doesn't return the start/end nodes for relationships for you, you can do something like this:
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = 1234
RETURN collect({rel: b, startnode: startnode(b), endnode: endnode(b)}), k
Hopefully that helps!
You get non distinct results, because you return both b and k
If you only want to get distinct b's use:
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = 1234 AND a<>b
RETURN DISTINCT b
You should also use parameters!
MATCH (a)-[k:nearby*]->(b)
WHERE ID(a) = {1} AND a<>b
RETURN DISTINCT b
ps.setInt(1,1234);

Resources