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

Reply via email to