32.3. User database with indexes
You have a user database, and want to retrieve users by name using indexes.
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.
IndexDefinition indexDefinition; try ( Transaction tx = graphDb.beginTx() ) { Schema schema = graphDb.schema(); indexDefinition = schema.indexFor( DynamicLabel.label( "User" ) ) .on( "username" ) .create(); tx.success(); }
Indexes are populated asynchronously when they are first created. It is possible to use the core API to wait for index population to complete:
try ( Transaction tx = graphDb.beginTx() ) { Schema schema = graphDb.schema(); schema.awaitIndexOnline( indexDefinition, 10, TimeUnit.SECONDS ); }
It’s time to add the users:
try ( Transaction tx = graphDb.beginTx() ) { Label label = DynamicLabel.label( "User" ); // Create some users 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(); }
And here’s how to find a user by id:
Note Please read Section 32.5, “Managing resources when using long running 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"; try ( Transaction tx = graphDb.beginTx() ) { try ( ResourceIterator<Node> users = graphDb.findNodesByLabelAndProperty( label, "username", nameToFind ).iterator() ) { ArrayList<Node> userNodes = new ArrayList<>(); while ( users.hasNext() ) { userNodes.add( users.next() ); } for ( Node node : userNodes ) { System.out.println( "The username of user " + idToFind + " is " + node.getProperty( "username" ) ); } } }
When updating the name of a user, the index is updated as well:
try ( Transaction tx = graphDb.beginTx() ) { 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(); }
When deleting a user, it is automatically removed from the index:
try ( Transaction tx = graphDb.beginTx() ) { 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(); }
In case we change our data model, we can drop the index as well:
try ( Transaction tx = graphDb.beginTx() ) { Label label = DynamicLabel.label( "User" ); for ( IndexDefinition indexDefinition : graphDb.schema() .getIndexes( label ) ) { // There is only one index indexDefinition.drop(); } tx.success(); }