i'm working with neo4j version 2.2.1. I would like to know how to delete a specific node using a cypher query in a java program containing a parameter.
i tried this but it wouldn't work :
Map<String, Object> params = new HashMap<String, Object>();
params.put("numero", "1");
String query1 ="MATCH (pe:Person) WHERE PeNumero={numero} DELETE pe";
Result result1 = graphDb.execute( query1, params);
Person is my node label, and PeNumero is one of its properties.
Thanks a lot, ghrs
In order to delete a node, you'll probably have to delete its relationships too. Otherwise deleting a node would leave "dangling" relationships, which wouldn't mean anything and that's not permitted. Try this instead:
MATCH (pe:Person)-[r]-(m) WHERE PeNumero={numero} DELETE r, pe;
so the problem is finally solved. I used a Cypher query to find the node, retrieve its id and then delete the node using a transaction that gets the node by id.It worked !
Thanks FrobberOfBits and cybersam.
Try like this
MATCH (pe:Person {PeNumero:{numero}})
OPTIONAL MATCH (pe)-[r]-(m)
DELETE r, pe;
It will delete that particular node and if that node having some relationships, then that relationships will get deleted.
You can check references here http://neo4j.com/docs/stable/query-delete.html
Related
I tried to delete a relationship, and this little-documented error shows up.
The query:
MATCH ()-[r:SendTo]-(n:Wallet)
WHERE NOT ()-[:BelongTo]->(n)
DELETE r
RETURN r
The whole error output:
Exception in thread "main" org.neo4j.driver.v1.exceptions.value.NotMultiValued: NULL is not a keyed collection
at org.neo4j.driver.internal.value.ValueAdapter.get(ValueAdapter.java:192)
at basicANeo4j.Importer.<init>(Importer.java:213)
at basicANeo4j.Importer.main(Importer.java:246)
When I checked the corresponding relationship, there is no property of it which is null:
<id>:595 value_bitcoin:20000000000outputIndex:defaultuniqueReferenceTran:bcaeee45968b5a08c88ed7a0d90a1275728eda356013465408197e9f77c634daNULLtranHashString:bcaeee45968b5a08c88ed7a0d90a1275728eda356013465408197e9f77c634datime:2016-01-01T22:55:26type:pubkeyhashvalue_dollar:86554.0estChanAddr:3KgtbGgaX2ngstNpvyv7LwpHSweVeqGbpM
I looked into ValueAdapter.class, this is the relevant code:
#Override
public Value get( String key )
{
throw new NotMultiValued( type().name() + " is not a keyed collection" );
}
Without any documentation, it does not help at all.
As Tomaz says, this is because you can't return a node or relationship you just deleted.
However, you can get a map "snapshot" of a node or relationship, delete the node or relationship, then return the snapshot.
Here's the article in the knowledge base.
I think this is because you are trying to return a null object because you deleted it first. I would try this
MATCH ()-[r:SendTo]-(n:Wallet)
WHERE NOT ()-[:BelongTo]->(n)
DELETE r
RETURN 'success'
You can return either a string, could return n if you are interested in which wallet had relationships deleted or you could not return anything.
I just realized where the error of keyed collection come from: while iterating through the records, I tried to print a property of the relationship, while the property does not exist for this relatioship. (I copied it from another part of my code without checking it and was convinced that it is the query which is the problem. So I missed that.)
I'm using neo4j-jdbc 2.3.2 as my neo4j client for java. When I executed following cypher query
match(p:Person) where p.id_number='761201948V' return p.id; it will return P2547228 as node id. I feel like id is same as other properties of the node as I can use it inside where clauses. But here I'm expecting an integer which can use inside this query START p=node('node.id') return p; Is this id is an internal thing to neo4j db? and is there a way to retrieve this id?
From the following two cyphers what is most efficient one?(if both referring same node)
START p=node('2547223') return p;
match(p:Person) where p.id='P2547228' return p;
You have to use the ID(x) function for this. Note, that ID(x) and x.id are a complete different thing. The former returns the internal node/relationship id managed by Neo4j itself. The latter gives the id property which is managed by the user and not by the database itself.
Also note, that a node/relationship ID is always numeric.
Using START is pretty much old school and shouldn't be used any more (except for accessing manual indexes):
start p=node(2547228) return p
This one is a equivalent statement. It is highly efficient since it just needs to do a simple seek operation on the node store:
match(p:Person) where id(p)=2547228 return p;
Looking for a property requires either a node label scan or a schema index lookup:
match(p:Person) where p.id=2547228 return p;
Just check out the query plans on your own by prefixing the statement with PROFILE.
In my Java code I have a query to match the shortest path from root to a leaf in my tree.
Strinq query = "Match path = (p:Root)-[*1..100]-(m:Leaf) "
+ "WITH p,m,path ORDER BY length(path) LIMIT 1 RETURN path";
However, when I try to query this as follows
SessionFactory sessionFactory = new SessionFactory("incyan.Data.Neo4j.Models");
Session session = sessionFactory.openSession("http://localhost:7474");
Object o = session(query, new HashMap<String,Object>());
o contains an ArrayList of LinkedHashMaps instead of mapped objects.
I cannot even determine the labels of the path elements and the start and end nodes of the relations.
What am I doing wrong?
The current neo4j-ogm release does not map query results to domain entities. Returning a path will only give you the properties of nodes and relationships in that path (in order, so you can infer the relationship start/end). ID's aren't returned by the Neo4j REST api currently used by the OGM for this particular operation and that's why they are missing. You may instead have to extract the ID's and return them as part of your query.
Mapping individual query result columns to entities will be available in a Neo4j-OGM 2.0 release.
I'm not sure about the Java bit, but if you use the shortestPath function (keyword?) your query should be more efficient:
MATCH path=shortestPath((p:Root)-[*1..100]-(m:Leaf))
RETURN path
Also, I don't know what your data model is like, but I would expect the labels on the nodes of your tree (I'm assuming it's a tree) to all be the same. You can tell if a node is a root or a leaf using Cypher:
MATCH path=shortestPath((root:Element)-[*1..100]-(leaf:Element))
WHERE NOT((root)-[:HAS_PARENT]->()) AND NOT(()-[:HAS_PARENT]->(leaf))
RETURN path
How should I get all the existing relationships between each two nodes in a graph in neo4j by java?
I want the results which this cypher query returns:
start r=rel(*) return r
so later I can change or delete some of them based on my conditions?
or get the start or end node of them.
this is what I have done so far:
Iterable<Relationship> rels=GlobalGraphOperations.at(db).getAllRelationships();
for (Relationship rel: rels )
{}
but I have error in this line:for (Relationship rel: rels )
the error is because does not know rels ,and wants to create a class for it.
I used this for indexing and it was working:
GlobalGraphOperations ggo = GlobalGraphOperations.at(db);
for (Relationship r : ggo.getAllRelationships()) {
//indexing code
}
try to get relationships on single node and check result
e.g.
Iterable<BatchRelationship> _itlRelationship= _neo.getRelationships(_empNodeId);
Iterator<BatchRelationship> _itRelationship= _itlRelationship.iterator();
while (_itRelationship.hasNext()) {}
Now I am using RESTFul API to interface with Neo4j. My issue is: for example I have already created a Node1 in Neo4j. Then I just want to create a Node2 and a relationship to connect to Node1. I know I need to query node from Neo4j and return a node. But how to do it? I am new in Neo4j please help.
And I have already build a delete function by using java to delete all nodes and relationships in Neo4j. Here is my code:
public String deleteAllNodeOrRelation() throws ClientHandlerException,
UniformInterfaceException, JDOMException {
String cypherPayload = "{\"query\": \"START a=node(*) MATCH a-[r?]-() DELETE a,r RETURN a\", \"params\":{}}";
String user_name = getUserName(cypherPayload);
return user_name;
}
is the query node function similar with this delete function? and to be noticed, I have properties stored in each node. The property name is "title". Someone told me I can query "title" to search and return the node1. But I still dont know how to do it....
Yes, you would have to enable auto-indexes for your domain-keys just do:
START u1=node:node_auto_index(name={user1}),
u2=node:node_auto_index(name={user2})
CREATE (u1)-[:KNOWS]->(u2)
you pass user1 and user2 as parameters to your function and to the cypher query call.
For some ways of how to call cypher from Java see: https://github.com/jexp/cypher-http-examples