Ok there, I found out something new, if I do the count outside of the transaction (ie. after tx.finish() ) then it works right, ie. in a different example: Node `one` has 100,100 out rels, time=7,954,653,001 tx.finish() time=1,525,669,261 Node `one` has 1,200,546 out rels
And as long as I create relationships inside the transaction, it will always show me(when I count) the number of added relationships + 100, even if on previous program run I had a transaction with more added relationships (ie. 200,000 as opposed to 100,000 now => shows 100,100) ok, here's the latest sample program: with this output ie. Node `one` has 99,100 out rels, time=9,265,459,688 tx.finish() time=1,221,787,378 counting outside of transaction... Node `one` has 1,399,546 out rels, time=353,716,303 /** * Licensed to Neo Technology under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Neo Technology licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.neo4j.examples; import java.io.*; import java.text.*; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.*; import org.neo4j.kernel.*; public class CalculateShortestPath { private static final int SHOWINFO_IF_COUNTING_REL_TOOK_MORE_THAN_ns = 2 * 300; private static final int SHOWINFO_IF_REL_TOOK_MORE_THAN_ns = 30000; private static final int SHOWEVERY_xTH_REL = 10000; private static final int HOWMANY_RELATIONSHIPS = 99000; private static final String DB_PATH = "neo4j-shortest-path"; private static final String NAME_KEY = "name"; private static RelationshipType KNOWS = DynamicRelationshipType .withName( "KNOWS" ); private static GraphDatabaseService graphDb; private static Index<Node> indexService; private static DecimalFormat commaDelimitedFormatter = new DecimalFormat( "###,###" ); public static String number( double val ) { return commaDelimitedFormatter.format( val ); } public static void main( final String[] args ) { // deleteFileOrDirectory( new File( DB_PATH ) );// XXX: graphDb = new EmbeddedGraphDatabase( DB_PATH ); indexService = graphDb.index().forNodes( "nodes" ); registerShutdownHook(); Transaction tx = graphDb.beginTx(); Node one = getOrCreateNode( "one" ); DynamicRelationshipType moo = DynamicRelationshipType.withName( "moo" ); try { for ( int i = 1; i <= HOWMANY_RELATIONSHIPS; i++ ) { long start = System.nanoTime(); Relationship rel = one.createRelationshipTo( graphDb.createNode(), moo ); // rel.setProperty( "relname", i ); long end = System.nanoTime(); if ( ( i % SHOWEVERY_xTH_REL == 0 ) || ( end - start > SHOWINFO_IF_REL_TOOK_MORE_THAN_ns ) ) { System.out.println( number( i ) + " timeDelta=" + number( end - start ) ); } } System.out.println( "counting..." ); long start = System.nanoTime(); Iterable<Relationship> rel = one.getRelationships( Direction.OUTGOING, moo ); long count = 0; long tstart = 0; for ( Relationship relationship : rel ) { long tend = System.nanoTime(); count++; if ( ( tend - tstart > SHOWINFO_IF_COUNTING_REL_TOOK_MORE_THAN_ns ) ) { System.out.println( number( count ) + " timeDelta=" + number( tend - tstart ) ); } tstart = System.nanoTime(); } long end = System.nanoTime(); System.out.println( "Node `" + one.getProperty( NAME_KEY ) + "` has " + number( count ) + " out rels, time=" + number( end - start ) ); // /* // * (Neo) --> (Trinity) // * \ ^ // * v / // * (Morpheus) --> (Cypher) // * \ | // * v v // * (Agent Smith) // */ // createChain( "Neo", "Trinity" ); // createChain( "Neo", "Morpheus", "Trinity" ); // createChain( "Morpheus", "Cypher", "Agent Smith" ); // createChain( "Morpheus", "Agent Smith" ); tx.success(); } finally { long start = System.nanoTime(); tx.finish(); long end = System.nanoTime(); System.out.println( "tx.finish() time=" + number( end - start ) ); } System.out.println( "counting outside of transaction..." ); long start = System.nanoTime(); Iterable<Relationship> rel = one.getRelationships( Direction.OUTGOING, moo ); long count = 0; for ( Relationship relationship : rel ) { count++; } long end = System.nanoTime(); System.out.println( "Node `" + one.getProperty( NAME_KEY ) + "` has " + number( count ) + " out rels, time=" + number( end - start ) ); // So let's find the shortest path between Neo and Agent Smith // Node neo = getOrCreateNode( "Neo" ); // Node agentSmith = getOrCreateNode( "Agent Smith" ); // // START SNIPPET: shortestPathUsage // PathFinder<Path> finder = GraphAlgoFactory.shortestPath( Traversal.expanderForTypes( KNOWS, Direction.BOTH ), 4 ); // Path foundPath = finder.findSinglePath( neo, agentSmith ); // System.out.println( "Path from Neo to Agent Smith: " + Traversal.simplePathToString( foundPath, NAME_KEY ) ); // END SNIPPET: shortestPathUsage // graphDb.shutdown(); } private static void createChain( String... names ) { for ( int i = 0; i < names.length - 1; i++ ) { Node firstNode = getOrCreateNode( names[i] ); Node secondNode = getOrCreateNode( names[i + 1] ); firstNode.createRelationshipTo( secondNode, KNOWS ); } } private static Node getOrCreateNode( String name ) { Node node = indexService.get( NAME_KEY, name ).getSingle(); if ( node == null ) { System.out.println( "creating new node with name=" + name ); node = graphDb.createNode(); node.setProperty( NAME_KEY, name ); indexService.add( node, NAME_KEY, name ); } return node; } private static void registerShutdownHook() { // Registers a shutdown hook for the Neo4j instance so that it // shuts down nicely when the VM exits (even if you "Ctrl-C" the // running example before it's completed) Runtime.getRuntime().addShutdownHook( new Thread() { @SuppressWarnings( "synthetic-access" ) @Override public void run() { System.out.println( "Shutting down database ..." ); graphDb.shutdown(); } } ); } private static void deleteFileOrDirectory( File file ) { if ( file.exists() ) { if ( file.isDirectory() ) { for ( File child : file.listFiles() ) { deleteFileOrDirectory( child ); } } file.delete(); } } } On Thu, Jul 21, 2011 at 5:01 AM, cyuczi eekc <[email protected]> wrote: > I should probably mention that I am using neo4j community (embedded) latest > sources up to date from github > > > On Thu, Jul 21, 2011 at 4:59 AM, cyuczi eekc <[email protected]> wrote: > >> Trying to count the relationships "the normal way" I find that oddly, I >> cannot see more than 100+x relationships, where x is the maximum number of >> relations ever added within a transaction. >> For example, if I add 91 relationships in a transation, and I count >> them, I have 91. I run the program again and I have 182, then I run the >> program again and I count 191, and any subsequent program runs will have the >> same 191 count. Is this a bug or am I missing something very important ?! >> Here's the sample code to try (run it 3 times and observe the >> ante-ante-last line on console: "Node `one` has 191 out rels, >> time=24,098,904"): >> (I don't know how I would place this code into a code block though) >> >> /** >> * Licensed to Neo Technology under one or more contributor >> * license agreements. See the NOTICE file distributed with >> * this work for additional information regarding copyright >> * ownership. Neo Technology licenses this file to you under >> * the Apache License, Version 2.0 (the "License"); you may >> * not use this file except in compliance with the License. >> * You may obtain a copy of the License at >> * >> * http://www.apache.org/licenses/LICENSE-2.0 >> * >> * Unless required by applicable law or agreed to in writing, >> * software distributed under the License is distributed on an >> * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >> * KIND, either express or implied. See the License for the >> * specific language governing permissions and limitations >> * under the License. >> */ >> package org.neo4j.examples; >> >> import java.io.*; >> import java.text.*; >> >> import org.neo4j.graphdb.*; >> import org.neo4j.graphdb.index.*; >> import org.neo4j.kernel.*; >> >> >> >> public class CalculateShortestPath { >> >> private static final int >> SHOWINFO_IF_COUNTING_REL_TOOK_MORE_THAN_ns = 2 * 300; >> private static final int >> SHOWINFO_IF_REL_TOOK_MORE_THAN_ns = 30000; >> private static final int SHOWEVERY_xTH_REL >> = 10000; >> private static final int HOWMANY_RELATIONSHIPS >> = 91; >> private static final String DB_PATH >> = "neo4j-shortest-path"; >> private static final String NAME_KEY >> = "name"; >> private static RelationshipType KNOWS >> = DynamicRelationshipType >> >> .withName( "KNOWS" ); >> >> private static GraphDatabaseService graphDb; >> private static Index<Node> indexService; >> private static DecimalFormat commaDelimitedFormatter >> = new DecimalFormat( "###,###" ); >> >> >> public static String number( double val ) { >> return commaDelimitedFormatter.format( val ); >> } >> >> >> public static String getTimeDelta( long start, long end ) { >> return commaDelimitedFormatter.format( end - start ); >> } >> >> >> public static void main( final String[] args ) { >> // deleteFileOrDirectory( new File( DB_PATH ) );// XXX: >> graphDb = new EmbeddedGraphDatabase( DB_PATH ); >> indexService = graphDb.index().forNodes( "nodes" ); >> registerShutdownHook(); >> Transaction tx = graphDb.beginTx(); >> try { >> Node one = getOrCreateNode( "one" ); >> DynamicRelationshipType moo = >> DynamicRelationshipType.withName( "moo" ); >> for ( int i = 1; i <= HOWMANY_RELATIONSHIPS; i++ ) { >> long start = System.nanoTime(); >> Relationship rel = one.createRelationshipTo( >> graphDb.createNode(), moo ); >> rel.setProperty( "relname", i ); >> long end = System.nanoTime(); >> if ( ( i % SHOWEVERY_xTH_REL == 0 ) || ( end - start > >> SHOWINFO_IF_REL_TOOK_MORE_THAN_ns ) ) { >> System.out.println( number( i ) + " timeDelta=" + >> number( end - start ) ); >> } >> } >> >> System.out.println( "counting..." ); >> long start = System.nanoTime(); >> Iterable<Relationship> rel = one.getRelationships( >> Direction.OUTGOING, moo ); >> long count = 0; >> long tstart = 0; >> for ( Relationship relationship : rel ) { >> long tend = System.nanoTime(); >> count++; >> if ( ( tend - tstart > >> SHOWINFO_IF_COUNTING_REL_TOOK_MORE_THAN_ns ) ) { >> System.out.println( number( count ) + " timeDelta=" + >> number( tend - tstart ) ); >> } >> tstart = System.nanoTime(); >> } >> long end = System.nanoTime(); >> System.out.println( "Node `" + one.getProperty( NAME_KEY ) + >> "` has " + number( count ) + " out rels, time=" >> + number( end - start ) ); >> >> // /* >> // * (Neo) --> (Trinity) >> // * \ ^ >> // * v / >> // * (Morpheus) --> (Cypher) >> // * \ | >> // * v v >> // * (Agent Smith) >> // */ >> // createChain( "Neo", "Trinity" ); >> // createChain( "Neo", "Morpheus", "Trinity" ); >> // createChain( "Morpheus", "Cypher", "Agent Smith" ); >> // createChain( "Morpheus", "Agent Smith" ); >> tx.success(); >> } finally { >> long start = System.nanoTime(); >> tx.finish(); >> long end = System.nanoTime(); >> System.out.println( "tx.finish() time=" + number( end - start >> ) ); >> } >> >> // So let's find the shortest path between Neo and Agent Smith >> // Node neo = getOrCreateNode( "Neo" ); >> // Node agentSmith = getOrCreateNode( "Agent Smith" ); >> // // START SNIPPET: shortestPathUsage >> // PathFinder<Path> finder = GraphAlgoFactory.shortestPath( >> Traversal.expanderForTypes( KNOWS, Direction.BOTH ), 4 ); >> // Path foundPath = finder.findSinglePath( neo, agentSmith ); >> // System.out.println( "Path from Neo to Agent Smith: " + >> Traversal.simplePathToString( foundPath, NAME_KEY ) ); >> // END SNIPPET: shortestPathUsage >> >> >> // graphDb.shutdown(); >> } >> >> >> private static void createChain( String... names ) { >> for ( int i = 0; i < names.length - 1; i++ ) { >> Node firstNode = getOrCreateNode( names[i] ); >> Node secondNode = getOrCreateNode( names[i + 1] ); >> firstNode.createRelationshipTo( secondNode, KNOWS ); >> } >> } >> >> >> private static Node getOrCreateNode( String name ) { >> Node node = indexService.get( NAME_KEY, name ).getSingle(); >> if ( node == null ) { >> node = graphDb.createNode(); >> node.setProperty( NAME_KEY, name ); >> indexService.add( node, NAME_KEY, name ); >> } >> return node; >> } >> >> >> private static void registerShutdownHook() { >> // Registers a shutdown hook for the Neo4j instance so that it >> // shuts down nicely when the VM exits (even if you "Ctrl-C" the >> // running example before it's completed) >> Runtime.getRuntime().addShutdownHook( new Thread() { >> >> @SuppressWarnings( "synthetic-access" ) >> @Override >> public void run() { >> System.out.println( "Shutting down database ..." ); >> graphDb.shutdown(); >> } >> } ); >> } >> >> >> private static void deleteFileOrDirectory( File file ) { >> if ( file.exists() ) { >> if ( file.isDirectory() ) { >> for ( File child : file.listFiles() ) { >> deleteFileOrDirectory( child ); >> } >> } >> file.delete(); >> >> } >> } >> } >> >> >> >> On Thu, Jul 21, 2011 at 3:39 AM, Michael Hunger < >> [email protected]> wrote: >> >>> Caching that result would require synchronizing it with every change >>> using up memory and performance (at every change) for something that can be >>> computed >>> >>> So far it has not been worth the effort. >>> >>> If you really need that value very often you could write a small >>> TransactionEventHandler that keeps the count updated for the nodes you're >>> interested in. You would then >>> ask this handler for the Rel-Count of a node, which would either compute >>> it (and add/register it to its cache) or just return it from the cache. >>> >>> Michael >>> >>> Am 20.07.2011 um 21:50 schrieb cyuczi eekc: >>> >>> > I guess I was hoping it(size/count) was cached in the database or the >>> > underlaying database would provide this somehow, ie. in berkeleydb >>> (java >>> > edition) there's a cursor.count() I could use (though I don't know how >>> they >>> > did it implementation-wise) >>> > >>> > Thanks! I needed to know that. >>> > >>> > On Wed, Jul 20, 2011 at 8:37 PM, Jim Webber <[email protected]> >>> wrote: >>> > >>> >> Hi, >>> >> >>> >> Responses from calling the Neo4j APIs are typically lazy, for >>> performance >>> >> reasons. So there's no way of eagerly counting the number of >>> relationships >>> >> unless you force eager evaluation as you've suggested below. >>> >> >>> >> Jim >>> >> >>> >> On 20 Jul 2011, at 11:13, cyuczi eekc wrote: >>> >> >>> >>> Is there a way to get the number of relationships without having to >>> >> iterate >>> >>> through (and count++) them? >>> >>> ie. rels=firstNode.getRelationships(); >>> >>> rels.size(); //doesn't actually exist >>> >>> _______________________________________________ >>> >>> Neo4j mailing list >>> >>> [email protected] >>> >>> https://lists.neo4j.org/mailman/listinfo/user >>> >> >>> >> _______________________________________________ >>> >> Neo4j mailing list >>> >> [email protected] >>> >> https://lists.neo4j.org/mailman/listinfo/user >>> >> >>> > _______________________________________________ >>> > Neo4j mailing list >>> > [email protected] >>> > https://lists.neo4j.org/mailman/listinfo/user >>> >>> _______________________________________________ >>> Neo4j mailing list >>> [email protected] >>> https://lists.neo4j.org/mailman/listinfo/user >>> >> >> > _______________________________________________ Neo4j mailing list [email protected] https://lists.neo4j.org/mailman/listinfo/user

