[Neo4j] Delete a RelationshipType
Hi, I have a graph with two different RelationshipType: R1, R2 I want to replace all RelationshipTypes with a new R3. It means that previous relations are exist but its types change to R3. Iterate over all nodes, delete previous relations and create new relation with the following source code: int pc = 0; Node ref = graphDb.getReferenceNode(); for (IteratorNode itr = graphDb.getAllNodes().iterator(); itr.hasNext();) { Node current_node = itr.next(); if (current_node.equals(ref)) continue; ArrayListLong current_relations = new ArrayListLong(); for (IteratorRelationship rel_itr = current_node.getRelationships().iterator(); rel_itr .hasNext();) { Relationship rel = rel_itr.next(); current_relations.add(rel.getId()); } for (long r : current_relations) updateRelation(r); if (++pc % 100 == 0) System.out.println(\t\t\t + pc); if (pc % 1 == 0) { System.out.println(\t\t\tsaving to disk...); tx.success(); tx.finish(); tx = graphDb.beginTx(); } } private void updateRelation(long relID) { Relationship rel = graphDb.getRelationshipById(relID); Node startNode = rel.getStartNode(); Node endNode = rel.getEndNode(); rel.delete(); startNode.createRelationshipTo(endNode, NodeRelationshipTypes2.related_to); } After running, size of the graph is changed from 2GB to 3.5GB and when I print the relationship types with: System.out.println(\tRelationship types:); for (IteratorRelationshipType rel_type_itr = graphDb.getRelationshipTypes().iterator(); rel_type_itr .hasNext();) System.out.println(\t\t + rel_type_itr.next().name()); R1, R2 and R3 are in the output. Why? I checked all node's relations, there is no relation which its type is equal to R1 or R2! Kind regards ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
Hi! After running, size of the graph is changed from 2GB to 3.5GB I think this is because the storage slots of the old relationships is not compacted but will be reused for new relationships in the future. and when I print the relationship types with: System.out.println(\tRelationship types:); for (IteratorRelationshipType rel_type_itr = graphDb.getRelationshipTypes().iterator(); rel_type_itr .hasNext();) System.out.println(\t\t + rel_type_itr.next().name()); R1, R2 and R3 are in the output. Why? The answer is in the javadocs: http://api.neo4j.org/current/org/neo4j/graphdb/GraphDatabaseService.html#getRelationshipTypes%28%29 Note that this method is guaranteed to return all known relationship types, but it does not guarantee that it won't return more than that (e.g. it can return historic relationship types that no longer have any relationships in the node space). /anders I checked all node's relations, there is no relation which its type is equal to R1 or R2! Kind regards ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
I think this is because the storage slots of the old relationships is not compacted but will be reused for new relationships in the future. I am curious, are there any 'developer tricks' for influencing when old slots are reused? For example, instead of adding the new relationships immediately after deleting old ones, but keeping a cache of 'relationships to add' and adding them a little later. Will that increase the chance of old slots being reused? I think this is relevant to cases where the developer wants to keep the database reasonably compact but does large amounts of deletion and creation. ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
I am curious, are there any 'developer tricks' for influencing when old slots are reused? For example, instead of adding the new relationships immediately after deleting old ones, but keeping a cache of 'relationships to add' and adding them a little later. Will that increase the chance of old slots being reused? My understanding is this: An id for every record and, correspondingly, a number of bytes in the file, are reserved the moment that, during a tx, a new entity is created. Conversely, the id of an entity is freed upon successful commit() of the tx that deleted it, although the space is still occupied but marked as free and available to be returned at the next request for a new entity. Note that all these operations have entity type scope, meaning that a freed Node does not in any way influence Relationship operations. The above lead to a strategy of performing and committing any deletes first and then, in a new tx, create all that is needed. If, during the same tx, a delete is made and then a create, the deleted id is not reused. I think this is relevant to cases where the developer wants to keep the database reasonably compact but does large amounts of deletion and creation. I think there was a similar discussion here some time ago and I seem to recall that the proposed solution for compacting a db after a long streak of deletes/inserts was to recreate the db in a new location. Hope that helps somewhat. cheers, CG ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
My understanding is this: And it is wrong. Consider the following snippet: GraphDatabaseService graphDb = new EmbeddedGraphDatabase(var/base); Transaction tx = graphDb.beginTx(); Node firstNode = graphDb.createNode(); Node secondNode = graphDb.createNode(); System.out.println(firstNode.getId()); System.out.println(secondNode.getId()); secondNode.delete(); Node thirdNode = graphDb.createNode(); System.out.println(thirdNode.getId()); tx.success(); tx.finish(); tx = graphDb.beginTx(); Node fourthNode = graphDb.createNode(); System.out.println(fourthNode.getId()); tx.success(); tx.finish(); graphDb.shutdown(); If the id pool was reused after a successful commit() (success() in the above code) as I described then, on a new db, this should print 1 2 3 2 but instead it prints 1 2 3 4 The id 2 is reused upon restart of the db. That will teach me to speak without checking first. What I did wrong is left as an exercise for tomorrow. cheers, CG ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
A db restart is required to start reusing free'd ids? Seems a bit drastic. I hope it happens sooner than that. ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user
Re: [Neo4j] Delete a RelationshipType
2010/10/31 Craig Taverner cr...@amanzi.com A db restart is required to start reusing free'd ids? Seems a bit drastic. I hope it happens sooner than that. As far as I know no id's are reused during one lifecycle of an EmbeddedGraphDatabase. It needs to be restarted to be able to discover old deleted ids and reuse them. However that is just the current implementation, it might change in the future. ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user -- Mattias Persson, [matt...@neotechnology.com] Hacker, Neo Technology www.neotechnology.com ___ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user