Neo4j学习笔记(2)——手动索引和模式索引

Stella981
• 阅读 701

和关系数据库一样,Neo4j同样可以创建索引来加快查找速度。

在关系数据库中创建索引需要索引字段和指向记录的指针,通过索引可以快速查找到表中的行。

在Neo4j中,其索引是通过属性来创建,便于快速查找节点或者关系。

手动索引

先来说一下怎样创建手动索引。

创建索引采用显示创建,就像添加节点一样添加索引项,一个索引项标识的是一个节点或者关系的属性值。

索引项中除了包含属性值,还存储了对正在索引的属性具有特定值的一个或多个节点的引用。

Neo4j学习笔记(2)——手动索引和模式索引

以上是一个使用email属性作为键值指向节点的索引。

先通过下面代码添加数据。

try (Transaction tx = graphDb.beginTx()) {
    // 添加数据
    Label label = Label.label("Student");
    Node node1 = graphDb.createNode(label);
    node1.setProperty("name", "王翠花");
    node1.setProperty("email", "hua@qq.com");
    Node node2 = graphDb.createNode(label);
    node2.setProperty("name", "李小明");
    node2.setProperty("email", "ming@163.com");
    Node node3 = graphDb.createNode(label);
    node3.setProperty("name", "杨小红");
    node3.setProperty("email", "hong@gmail.com");
    node1.createRelationshipTo(node2, RelTypes.IS_FRIEND_OF);
    node1.createRelationshipTo(node3, RelTypes.IS_FRIEND_OF);
        // 提交事务
        tx.success();
}

 通过Neo4j查看,添加成功。

Neo4j学习笔记(2)——手动索引和模式索引

下面来创建索引。

Neo4j中使用IndexManager来管理索引,然后通过索引标识符来访问索引。

IndexManager indexManager = graphDb.index();
Index<Node> stuIndex = indexManager.forNodes("students");

上面个两行代码通过students向索引管理器去请求获得一个索引。

假如索引不存在则会自动创建。

因为是手动创建索引,所以还需要告诉数据库要添加的属性和对应的节点。

stuIndex.add(node1, "email", "hua@qq.com");
stuIndex.add(node2, "email", "ming@163.com");
stuIndex.add(node3, "email", "hong@gmail.com");

要添加一个节点到索引中,需要提供三个参数:需要索引的节点索引键索引的值

索引创建好之后,来尝试通过索引查找节点。

try (Transaction tx = graphDb.beginTx()) {
    String stuEmail = "hua@qq.com";
    // 获得索引
    IndexManager indexManager = graphDb.index();
    Index<Node> stuIndex = indexManager.forNodes("students");
    // 获得结果集
    IndexHits<Node> indexHits = stuIndex.get("email", stuEmail);
    // getSingle()会返回唯一结果,不唯一的话返回null
    Node stu = indexHits.getSingle();
    System.out.println(stu.getProperty("name", new String()));
}
//Output
王翠花

如果一个索引对应着多个节点,例如如果将年龄作为索引键,那么会有多个学生节点有着相同的年龄。

这种情况迭代IndexHits即可。有两点需要注意:

  1. IndexHits是一次性迭代,不能重复使用。
  2. 使用完IndexHits后应该关闭。如果所有结果都已迭代,IndexHits会自动关闭,否则需要调用close()方法手动关闭。

在关系数据库中,如果更改有索引的数据,索引也会跟着自动更新。

但是对于Neo4j中采用手动方式创建的索引,Neo4j并不会随着数据的改变而自动更新。

既然没有这种机制,那么只能采用一种笨方法,就是“先删除后添加”等于“更新”。

删除索引使用Index的remove()方法。

try (Transaction tx = graphDb.beginTx()) {
    String stuEmail = "hua@qq.com";
    // 获得索引
    IndexManager indexManager = graphDb.index();
    Index<Node> stuIndex = indexManager.forNodes("students");
    // 获得要删除索引对应的节点
    Node stuNode = stuIndex.get("email", stuEmail).getSingle();
    // 删除索引
    stuIndex.remove(stuNode, "email", stuNode.getProperty("email"));
    // 输出
    for (Node n : stuIndex.query("email", "*")) {
        System.out.println(n.getProperty("name"));
    }}
// Output
李小明
杨小红

可以看到一个索引项已经删除,这时重新对节点的属性进行设置,然后调用索引的add()方法就能完成手动的更新。

如果想删除整个索引,使用delete()方法。

indexManager.forNodes(indexName).delete();

相对于对节点建索引,关系索引很少用到,因为需要查询的对象一般都是实体,也就是节点。

虽然可以手动创建和维护索引,但是感觉很麻烦,下面介绍由数据库自动创建和维护索引的方法。

模式索引

模式索引和关系数据库中的索引很相似。

每一个索引会对应一个标签和一组属性。例如对学生的姓名name进行索引,你只需要定义索引,数据库会负责维护它们。

无论是更新还是删除节点,索引都会自动更新或者删除。

创建模式索引的方法如下:

IndexDefinition indexDefinition;
try (Transaction tx = graphDb.beginTx()) {
    Schema schema = graphDb.schema();
    indexDefinition = schema.indexFor(Label.label("Student")).on("name").create();
    tx.success();
}

首先要获取数据库的模式,然后提供LabelProperty就完成了索引的创建,比手动创建简单了不少。

查询也同样简单,使用ResourceIterator存放结果集。

需要注意,如果ResourceIterator没有完全迭代,则需要使用close()方法手动关闭。

try (Transaction tx = graphDb.beginTx()) {
    ResourceIterator<Node> stus = graphDb.findNodes(Label.label("Student"), "name", "王翠花");
    while (stus.hasNext()) {
        System.out.println(stus.next().getProperties("name", "email"));
    }
    tx.success();
}

输出结果:

{name=王翠花, email=hua@qq.com}

删除索引的方法:

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

自动索引

《Neo4j 实战》这本书中的数据库版本是2.x,书中提到了自动索引,一种通过配置文件来创建索引的方法。

但是在目前的3.x版本中已经废弃,建议使用模式索引代替。

Neo4j学习笔记(2)——手动索引和模式索引

何时使用索引

《你知道数据库索引的工作原理吗》看完这篇文章,复习了关系数据库中的索引,也对理解图数据库的索引有所帮助,因为两者大同小异。

创建索引都是为了加快查找速度,但是索引的缺点就是会占用额外的磁盘空间,索引太多可能会导致磁盘空间不足,在进行插入和更新操作时也会影响性能。

下图是使用索引和不使用索引查找搜索所有节点所需要的时间对比:

Neo4j学习笔记(2)——手动索引和模式索引

图片来源:《Neo4j 实战》

可以看到使用索引大大加快了查找速度。但是有时在查询上提高的性能可能会被抵消。

下图显示了随着节点数量的增加,创建一个新节点所需的时间,有索引情况下需要的时间差不多是无索引的两倍。

Neo4j学习笔记(2)——手动索引和模式索引

图片来源:《Neo4j 实战》

所以在创建索引时要有所权衡,对于那写频繁更新和创建的数据要谨慎选择索引。


 转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/8182376.html

参考资料

https://neo4j.com/docs/java-reference/3.2/#tutorials-java-embedded-index

《Neo4j 实战》

点赞
收藏
评论区
推荐文章
添砖java的啾 添砖java的啾
3年前
distinct效率更高还是group by效率更高?
目录00结论01distinct的使用02groupby的使用03distinct和groupby原理04推荐groupby的原因00结论先说大致的结论(完整结论在文末):在语义相同,有索引的情况下groupby和distinct都能使用索引,效率相同。在语义相同,无索引的情况下:distinct效率高于groupby。原因是di
Wesley13 Wesley13
3年前
SQL
当数据库中数据量特别大的时候,查询的速度就比较慢,这时候需要添加索引,来提高查询速度。索引的优点1通过创建唯一索引,可以保证数据库表中每行数据的唯一性。2加快数据查询速度3在使用分组和排序进行数据查询时,可以显著的减少查询中分组和排序的时间索引的缺点1维护索引需要消耗数据库资源2索引需要占用磁盘空间,索引文件可能会比数据
Wesley13 Wesley13
3年前
MySQL索引的索引长度问题
MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制。在MyISAM表中,创建组合索引时,创建的索引长度不能超过1000,注意这里索引的长度的计算是根据表字段设定的长度来标量的,例如:createtabletest(idint,name1varchar(300),name2varchar(300),nam
Wesley13 Wesley13
3年前
mysql之索引
一.索引:索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中1.1.创建一个索引:mysqlcreateindexix_classontb3(class_id);QueryOK,0rowsaffected(0.02sec)
Stella981 Stella981
3年前
ES中删除索引的mapping字段时应该考虑的点
1.创建新索引2.新索引创建新mapping3.原索引导出数据到新索引4.新索引创建原索引一致的别名5.删除原索引针对于第四步:这个就要用到索引别名了,如果你最开始建索引的时候没有考虑设计索引别名,那就杯具了。你可以把索引的名称设置成name\_v1 别名设置为name,然后代码里面访问搜索的时候连接的其实是别名na
Wesley13 Wesley13
3年前
MongoDB学习笔记_5_索引
索引概念建立指定键值及所在文档中的存储位置对照关系清单。使用索引可以方便我们快速查找,减少遍历次数,提高效率。操作创建索引db.collection_name.ensureIndex()功能:创建索引参数:提供索引的类别选项
Stella981 Stella981
3年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
Wesley13 Wesley13
3年前
mysql组合索引与字段顺序
很多时候,我们在mysql中创建了索引,但是某些查询还是很慢,根本就没有使用到索引!一般来说,可能是某些字段没有创建索引,或者是组合索引中字段的顺序与查询语句中字段的顺序不符。看下面的例子:假设有一张订单表(orders),包含order\_id和product\_id二个字段。一共有31条数据。符合下面语句的数据有5条。执行下面的s
Wesley13 Wesley13
3年前
MongoDB性能篇
一、索引MongoDB提供了多样性的索引支持,索引信息被保存在system.indexes中,且默认总是为\_id创建索引,它的索引使用基本和MySQL等关系型数据库一样。其实可以这样说说,索引是凌驾于数据存储系统之上的另一层系统,所以各种结构迥异的存储都有相同或相似的索引实现及使用接口并不足为奇。1.基础索引在字段age
3A网络 3A网络
2年前
什么是走索引?
什么是走索引?索引是一种利用某种规则的数据结构与实际数据的关系加快数据查找的功能。我们的数据库中存储有大量的内容,而索引能够通过数据节点,根据特定的规则和算法快速查找到节点对应的实际文件的位置。简单来说索引就像书的目录,能够帮助我们准确定位到书籍具体的内容。最近在学习索引的时候遇到了一个问题,下面我们通过重现的方式来看一下。首先建立一个如下测试表:javas