I have implemented py2neo with ogm, however I cannot get the search functionality to work like it should. Below I have my cypher query (directly to the Neo4j db) with 'rpt_id' and 'country_code' as GraphObjects in the graph with those as the primary keys of the graph. The relationship between them is PART_OF.
MATCH (m:Column {name: '{rpt_id}'}), (n:Column {name:'{country_code}'}),
p = shortestPath((m)-[:PART_OF*..4]-(n))
RETURN p
I expect a response of the Tables (another ogm node) to go through to get to country_code, however, nothing is being returned.
If nodes definitely exist that match rpt_id and country_code I expect the problem is the use of ticks around your parameters. I would re-write the query as follows:
MATCH (m:Column {name: {rpt_id} }), (n:Column {name: {country_code} }), p = shortestPath((m)-[:PART_OF*..4]-(n))
RETURN p
Related
I am trying to create relationship between two nodes using apoc.merge.relationship, but it creates two same relationships, which I can see by search. They both have same direction and everything is the same although from query it's obvious that newLink.id is identifier. I hope someone can show me what is wrong with my cypher query.
UNWIND [{
color:'#82abd1', direction:'true', id:'q', index:0, linkType:'a',
source:'46166.a690c888-e3d5-41ed-8469-79a88cce8388', status:'approved',
target:'46163.a690c888-e3d5-41ed-8469-79a88cce8388', type:'Applies for', value:2
}] AS newLink
MATCH
(fNode:Node {id: newLink.source}),
(sNode:Node {id: newLink.target})
CALL apoc.merge.relationship(
fNode,
'Label',
{id: newLink.id},
apoc.map.clean(newLink, ['id','type'],[]),
sNode,
apoc.map.clean(newLink, ['id','type'],[])
)
YIELD rel
RETURN DISTINCT 'true';
my search query is
MATCH ()-[rel]-() RETURN COUNT(rel)
My query was finding same relationships for both (node1)-[rel]-(node2) and for (node2)-[rel]-(node1). So one way to avoid this situation is using ID(node1)>ID(node2), which compares nodes id given by neo4j.
I am new to Neo4j and is developing a small site.
I have setup the nodes and relationships between them. For most of the paired nodes, I created a mutual link. For example:
Zeus - FATHER -> Apollo
Appollo - SON -> Zeus
I used shortestPath to find the possible shortest path between these two:
MATCH (o1 { name: 'Apollo' }),(o2 { name: 'Zeus' }), p = shortestPath((o1)-[*..6]-(o2)) RETURN nodes(p), relationships(p)
The result is that it returns "FATHER" instead of "SON".
If I change the query to [*..6]->(o2), "SON" is returned.
But I need to consider the search may make o1 a node with no outgoing relationship, in which case, the above-modified query fails.
So:
The original query can cope with nodes with no outgoing relationship, but may return wrong relationship.
The modified query can return right relationship (so far) but can't cope with "no out relation" nodes.
I can of course change every node to have at least one outgoing relation to fix Issue 2 but that will be too redundant.
Hope to get your advice.
It's a bad practice to create bidirectional relationships like you do, specially when it's a bijection.
You are duplicating some data in the database (it's obvious that if Zeus is the father of Apollo, Apollo is the son of Zeus).
This query :
MATCH
(o1 { name: 'Apollo' }),
(o2 { name: 'Zeus' }),
p = shortestPath((o1)-[*..6]-(o2))
RETURN nodes(p), relationships(p)
search only one shortestpath. But due to the duplication, there is in fact two shortestpaths. You can replace the shortestpath function by the allshortestpaths to find all. So youwill have the son and father result.
Or you can also give to the shortestpath function, a list of relationship type thath it can traverse like this:
MATCH
(o1 { name: 'Apollo' }),
(o2 { name: 'Zeus' }),
p = shortestPath((o1)-[:FATHER*..6]-(o2))
RETURN nodes(p), relationships(p)
I have 3 types of nodes - Challenge, Entry and User, and 2 relationships between these nodes: (Entry)-[POSTED_BY]->(User) and (Entry)-[PART_OF]->(Challenge).
Here is what I'm trying to accomplish:
- I have an existing Challenge, and I can identify it by its ID (internal neo4j id)
- I also have an existing User, and I can identify it by its id (not the same as neo4j internal id)
- Given the existing Challenge and User, I need to create a new Entry node, and link it with the Challenge node with a PART_OF relationship.
- In addition, I need to link the new Entry with the User node by the POSTED_BY relationship
- I want to achieve the above in a single Cypher query statement, if possible
This is what I'm trying:
MATCH (c:Challenge)
WHERE (id(c) = 240),
MATCH (u:User {id: '70cf6846-b38a-413c-bab8-7c707d4f46a8'})
CREATE (e:Entry {name: "My Entry"})-[:PART_OF]->(c), (u)<-[r:POSTED_BY]-(e)
RETURN e;
However, this is failing as it seems I cannot match two nodes with the above syntax. However, if I match the Challenge with a non-internal property, say name, it seems to work:
MATCH (c:Challenge {name: "Challenge Name"),
MATCH (u:User {id: '70cf6846-b38a-413c-bab8-7c707d4f46a8'})
CREATE (e:Entry {name: "My Entry"})-[:PART_OF]->(c), (u)<-[r:POSTED_BY]-(e)
RETURN e;
However, as I mentioned above, I want to match the neo4j internal Node ID for the Challenge, and I'm not sure if there's a way to match that other than by using the WHERE id(c) = 232 clause.
Your syntax is almost correct, but you don't need the comma between the WHERE and the next MATCH.
MATCH (c:Challenge)
WHERE id(c) = 240
MATCH (u:User {id: '70cf6846-b38a-413c-bab8-7c707d4f46a8'})
CREATE (e:Entry {name: "My Entry"})-[:PART_OF]->(c), (u)<-[r:POSTED_BY]-(e)
RETURN e;
graph snippet
I have a Shape with a list of Points.
I have the following requirements:
1) retrieve an ordered set of Points;
2) insert/remove a Point and preserve the order of the rest of the Points
I can achieve this by:
A) Point has a sequence integer property that could be used to order;
B) Add a :NEXT relationship between each Point to create a linked list.
I'm new to Neo4j so not sure which approach is preferable to satisfy the requirements?
For the first requirement, I wrote the following queries and found the performance for the traversal to be poor but Im sure its a badly constructed query:
//A) 146 ms
Match (s:Shape {id: "1-700-y11-1.1.I"})-[:POINTS]->(p:Point)
return p
order by p.sequence;
//B) Timeout! Bad query I know, but dont know the right way to go about it!
Match path=(s:Shape {id: "1-700-y11-1.1.I"})-[:POINTS]->(p1:Point)-[:NEXT*]->(p2:Point)
return collect(p1, p2);
To get ordered list of points use a slightly modified version of the second query:
Match path=(s:Shape {id: "1-700-y11-1.1.I"})-[:POINTS]->(P1:Point)
-[:NEXT*]-> (P2:Point)
WHERE NOT (:Point)-[:NEXT]->(P1) AND
NOT (P2)-[:NEXT]->(:Point)
RETURN TAIL( NODES( path) )
And for example query to delete:
WITH "id" as pointToDelete
MATCH (P:Point {id: pointToDelete})
OPTIONAL MATCH (Prev:Point)-[:NEXT]->(P)
OPTIONAL MATCH (P)-[:NEXT]->(Next:Point)
FOREACH (x in CASE WHEN Prev IS NOT NULL THEN [1] ELSE [] END |
MERGE (Prev)-[:NEXT]->(Next)
)
DETACH DELETE P
I am trying to figure out how to limit a shortest path query in cypher so that it only connects "Person" nodes containing a specific property.
Here is my query:
MATCH p = shortestPath( (from:Person {id: 1})-[*]-(to:Person {id: 2})) RETURN p
I would like to limit it so that when it connects from one Person node to another Person node, the Person node has to contain a property called "job" and a value of "engineer."
Could you help me construct the query? Thanks!
Your requirements are not very clear, but if you simply want one of the people to have an id of 1 and the other person to be an engineer, you would use this:
MATCH p = shortestPath( (from:Person {id: 1})-[*]-(to:Person {job: "engineer"}))
RETURN p;
This kind query should be much faster if you also created indexes for the id and job properties of Person.