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.
Note Schema changes and data changes are not allowed in the same transaction. Each transaction must either change the schema or the data, but not both. |
IndexDefinition indexDefinition; try ( Transaction tx = graphDb.beginTx() ) { Schema schema = graphDb.schema(); indexDefinition = schema.indexFor( Label.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 is also possible to query the progress of the index population:
try ( Transaction tx = graphDb.beginTx() ) { Schema schema = graphDb.schema(); System.out.println( String.format( "Percent complete: %1.0f%%", schema.getIndexPopulationProgress( indexDefinition ).getCompletedPercentage() ) ); }
It’s time to add the users:
try ( Transaction tx = graphDb.beginTx() ) { Label label = Label.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(); }
Note Please read Section 32.6, “Managing resources when using long running transactions” on how to properly close |
And here’s how to find a user by id:
Label label = Label.label( "User" ); int idToFind = 45; String nameToFind = "user" + idToFind + "@neo4j.org"; try ( Transaction tx = graphDb.beginTx() ) { try ( ResourceIterator<Node> users = graphDb.findNodes( label, "username", nameToFind ) ) { 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 = Label.label( "User" ); int idToFind = 45; String nameToFind = "user" + idToFind + "@neo4j.org"; for ( Node node : loop( graphDb.findNodes( 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 = Label.label( "User" ); int idToFind = 46; String nameToFind = "user" + idToFind + "@neo4j.org"; for ( Node node : loop( graphDb.findNodes( 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 = Label.label( "User" ); for ( IndexDefinition indexDefinition : graphDb.schema() .getIndexes( label ) ) { // There is only one index indexDefinition.drop(); } tx.success(); }