我有一个Java程序执行Neo4j的Cypher查询,每取5000条记录需要20几秒,给节点属性增加索引后,时间减少到2秒,速度提升了10倍。
以下是给节点属性增加索引的Java代码(Neo4j 3.4.4社区版):
package neo4j;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
public class kg_n2o_create_index {
public static void main(String[] args) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date())+" kg_n2o_create_index.java开始");
System.out.println("开始创建索引");
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(new File("/data/neo4j-community-3.4.4/data/databases/kg.db")); //引号里面填db目录
//要创建的索引有两个:cust节点的cust_id属性,和tel节点的tel_no属性。我这里在创建索引前,先做了一个删除索引的操作,根据实际需要而定。
try (org.neo4j.graphdb.Transaction tx1 = graphDb.beginTx()) {
//删除索引
Label label = Label.label("cust");
//遍历cust节点的所有索引并删除
for (IndexDefinition indexDefinition : graphDb.schema().getIndexes(label)) {
indexDefinition.drop();
}
//遍历tel节点的所有索引并删除
label = Label.label("tel");
for (IndexDefinition indexDefinition : graphDb.schema().getIndexes(label)) {
// There is only one index
indexDefinition.drop();
}
//创建索引
Schema schema = graphDb.schema();
IndexDefinition indexDefinition;
//给cust节点的cust_id属性创建索引
indexDefinition = schema.indexFor(Label.label("cust")).on("cust_id").create();
//给tel节点的tel_no属性创建索引
indexDefinition = schema.indexFor(Label.label("tel")).on("tel_no").create();
//提交事务
tx1.success();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("结束创建索引");
System.out.println(df.format(new Date())+" kg_n2o_create_index.java结束");
}
}
注意事项
用Java代码创建索引要在Neo4j服务关闭的情况下,索引创建完之后,再启动服务,这时候索引状态初始为POPULATING 。在浏览器执行:schema命令显示如下:
Indexes
ON :cust(cust_id) POPULATING
ON :tel(tel_no) POPULATING
接下来开始生成索引,需要花一点时间,我这里是两三分钟。索引生成之后的状态为ONLINE:
Indexes
ON :cust(cust_id) ONLINE
ON :tel(tel_no) ONLINE
如果在索引正在创建而还未完成的过程中,重启了服务,索引状态会变为FAILED:
Indexes
ON :cust(cust_id) FAILED
ON :tel(tel_no) FAILED
No constraints
综上,如果是用Java代码创建Neo4j索引,不是执行完创建索引命令就会生成索引,而是要先启动服务,等待索引状态由POPULATING变为ONLINE,然后才可以使用索引。
完毕。