Neo4j match using a list - neo4j

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;

Related

How to continue executing a Neo4J Cypher request after MATCH is not matched?

I have the following params in my Neo4J:
{
"lists": [
{
"from": "someone",
"to": "somebody"
}
]
}
And the following query:
MATCH (c:Concept{name:'infranodus'}) WITH c, $lists AS list
UNWIND CASE WHEN list = [{}] THEN [null] ELSE list END AS l
WITH l
MATCH (cp1:Concept{name:l.from})
WITH cp1
MATCH (cp2:Concept{name:'somebody'})
RETURN cp1,cp2;
The query above will work.
However, if I replace l.from with a non-existent parameter, e.g. l.about, then — as the match doesn't happen — the second cp2 match doesn't fire.
How can I change this behavior and continue executing this query even if cp1 is not found? Maybe there's a way to pass on a dummy variable as a result?
MATCH (c:Concept{name:'infranodus'}) WITH c, $lists AS list
UNWIND CASE WHEN list = [{}] THEN [null] ELSE list END AS l
WITH l
MATCH (cp1:Concept{name:l.about})
WITH cp1
MATCH (cp2:Concept{name:'somebody'})
RETURN cp1,cp2;
Use OPTIONAL MATCH. If there is no match is found, then it will use NULL for the missing part of the pattern. It is similar to outer join in SQL.
NEW:
OPTIONAL MATCH (cp1:Concept{name:l.about})
OLD:
MATCH (cp1:Concept{name:l.about})
You can maybe replace it with an IN predicate ?
For eg :
WITH {from: 'Matt Olg', about: 'Matthew Olg'}
AS l
MATCH (n:Person)
WHERE n.name IN [l.from, l.to]
RETURN n.name
╒══════════╕
│"n.name" │
╞══════════╡
│"Matt Olg"│
└──────────┘

To get all nodes and path from edge to root using neo4j

I want to get all nodes information with paths from edge to root node.Using one of the edge property.
This is the three layer node structure.
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[p:Parent*0..]-(c:Child) RETURN c,g,p
This will return only B,C nodes with relationship like this
cypher used
CREATE (p: Parent{name : '1'} ) RETURN p
MATCH (p:Parent) WHERE p.name = '1' CREATE (c: Child{name : '2'} )<-[:parentToChild]-(p) RETURN p
MATCH (c:Child) WHERE c.name = '3' CREATE (g: GrandChild {name : '2'} )<-[:childToGrandChild]-(c) RETURN c
Please help..
You have missed parentTochild relationship which will be like,
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[parentToChild*0..]-(p:Parent)
RETURN c,g,p
Try this :
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)
MATCH (c)<-[p:Parent*0..]-(c2:Child)
RETURN c,c2,g,p

How to check if node globally exists and set condition on it in Cypher?

I'm struggling with problem of creating query in Cypher.
Let's use this graph as an example:
MERGE(a:Person {name:'Alice', age:38, eyes:'brown'})
MERGE(c:Person {name:'Charlie', age:53, eyes:'green'})
MERGE(d:Person {name:'Daniel', age:54, eyes:'brown'})
MERGE(b:Person {name:'Bob', age:25, eyes:'blue'})
MERGE(a)-[:KNOWS]->(c)
MERGE(a)-[:KNOWS]->(b)
MERGE(c)-[:KNOWS]->(d)
MERGE(b)-[:KNOWS]->(d)
I would like to have query that returns me nodes with name = 'Alice' only if there aren't any nodes with name = 'Bob'. So if there is Bob I would like to see no results.
Here is what I've tried:
1) With exists()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NOT EXISTS ((n {name: 'Bob'})-[*1..3]->(b))
RETURN p
But it returns all nodes and relationships.
2) With none()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.name = 'Bob')
RETURN p
This returned all nodes, without Bob...
3) with any()
MATCH p =(n)-[*1..3]->(b)
WHERE n.name = 'Alice' AND NOT ANY (x IN nodes(p) WHERE x.name = 'Bob')
RETURN p
But this gave me the same result as above.
I'm running out of ideas how to return Alice only if Bob is not present.
What I would expect from query is to return Alice when I delete Bob, but when such node exists - nothing.
Any help is appreciated:)
Thanks!
You should try this query :
MATCH (n:Person {name:'Alice'})
WHERE NOT (n)-[:KNOWS*..3]-(:Person {name:'Bob'})
RETURN n

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);

Neo4j - minimum value from array properties

How do I get with cypher the minimum value of array with properties?
MATCH (n)-[r]->(m) RETURN n,m,min(r.timestamps)
Above query does not work.
r has an array with timestamps r.timestamps
How to get the lowest value of timestamps?
You can use unwind:
MATCH (n)-[r]->(m)
UNWIND r.timestamps as timestampts
RETURN n, m, min(timestampts)
I found an answer like this, but it looks ugly
MATCH
(h1)-[r]-(h2)
RETURN h1, h2,
reduce(minTimestamp = 999999999999999999, t IN r.timestamps | CASE WHEN minTimestamp < t THEN minTimestamp ELSE t END)

Resources