4.4. User database with schema based indexing

You have a user database, and want to retrieve users by name using schema based indexing.

[Tip]Tip

The source code used in this example is found here: EmbeddedNeo4jWithNewIndexing.java

To begin with, we start the database server

GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );

Then we have to configure the database to index users by name. This only needs to be done once.

New indexes are populated asynchronously. It is possible to use the core API to wait for index population to complete.

GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );

It’s time to add the users:

Transaction tx = graphDb.beginTx();
try
{
    Label label = DynamicLabel.label( "User" );

    // Create some users and index their names with the new IndexingService
    for ( int id = 0; id < 100; id++ )
    {
        Node userNode = graphDb.createNode( label );
        userNode.setProperty( "username", "user" + id + "@neo4j.org" );
    }
    System.out.println( "Users created" );
    tx.success();
}
finally
{
    tx.finish();
}

And here’s how to find a user by id:

[Note]Note

Please read Section 4.5, “Managing resources when not using transactions” on how to properly close ResourceIterators returned from index lookups.

Label label = DynamicLabel.label( "User" );
int idToFind = 45;
String nameToFind = "user" + idToFind + "@neo4j.org";
ResourceIterator<Node> users = graphDb.findNodesByLabelAndProperty( label, "username", nameToFind ).iterator();
try
{
    while ( users.hasNext() )
    {
        Node node = users.next();
        System.out.println( "The username of user " + idToFind + " is " + node.getProperty( "username" ) );
    }
}
finally
{
    // alternatively use a transaction
    users.close();
}

When updating the name of a user, the index is updated as well:

Transaction tx = graphDb.beginTx();
try
{
    Label label = DynamicLabel.label( "User" );
    int idToFind = 45;
    String nameToFind = "user" + idToFind + "@neo4j.org";

    for (Node node : graphDb.findNodesByLabelAndProperty( label, "username", nameToFind ) )
    {
        node.setProperty( "username", "user" + (idToFind+1) + "@neo4j.org" );
    }
    tx.success();
}
finally
{
    tx.finish();
}

When deleting a user, it is automatically removed from the index:

Transaction tx = graphDb.beginTx();
try
{
    Label label = DynamicLabel.label( "User" );
    int idToFind = 46;
    String nameToFind = "user" + idToFind + "@neo4j.org";

    for (Node node : graphDb.findNodesByLabelAndProperty( label, "username", nameToFind ) )
    {
        node.delete();
    }
    tx.success();
}
finally
{
    tx.finish();
}

In case we change our data model, we can drop the index as well:

Transaction tx = graphDb.beginTx();
try
{
    Label label = DynamicLabel.label( "User" );
    for ( IndexDefinition indexDefinition : graphDb.schema().getIndexes(label) )
    {
        // There is only one index
        indexDefinition.drop();
    }

    tx.success();
}
finally
{
    tx.finish();
}