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

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

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

手动索引

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

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

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

以上是一个使用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中使用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 实战》

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

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

图片来源:《Neo4j 实战》

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


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

参考资料

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

《Neo4j 实战》

Neo4j学习笔记(2)——数据索引的更多相关文章

  1. python库学习笔记——Pandas数据索引:ix、loc、iloc区别

    Different Choices for Indexing 1. loc--通过行标签索引行数据 1.1 loc[1]表示索引的是第1行(index 是整数) import pandas as pd ...

  2. Mysql数据库学习笔记之数据库索引(index)

    什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...

  3. SQL反模式学习笔记13 使用索引

    目标:优化性能 改善性能最好的技术就是在数据库中合理地使用索引.  索引也是数据结构,它能使数据库将指定列中的某个值快速定位在相应的行. 反模式:无规划的使用索引 1.不使用索引或索引不足 2.使用了 ...

  4. Windows phone 8 学习笔记(2) 数据文件操作

    原文:Windows phone 8 学习笔记(2) 数据文件操作 Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方 ...

  5. #学习笔记#JSP数据交互

    #学习笔记#JSP数据交互 数据库的使用方式:   当用户在第一个页面的查询框输入查询语句点提交的时候我们是用什么样的方式完成这个查询的? 答:我们通过在第一个页面提交表单的形式,真正的数据库查询时在 ...

  6. ArcGIS案例学习笔记_3_2_CAD数据导入建库

    ArcGIS案例学习笔记_3_2_CAD数据导入建库 计划时间:第3天下午 内容:CAD数据导入,建库和管理 目的:生成地块多边形,连接属性,管理 问题:CAD存在拓扑错误,标注位置偏移 教程:pdf ...

  7. GIS案例学习笔记-CAD数据分层导入现有模板实例教程

    GIS案例学习笔记-CAD数据分层导入现有模板实例教程 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 1. 原始数据: CAD数据 目标模板 2. 任务:分5个图层 ...

  8. ArcGIS案例学习笔记-CAD数据自动拓扑检查

    ArcGIS案例学习笔记-CAD数据自动拓扑检查 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 功能:针对CAD数据,自动进行拓扑检查 优点:类别:地理建模项目实例 ...

  9. Windows phone 8 学习笔记(2) 数据文件操作(转)

    Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方.本节主要讲解它们的用法以及相关限制性.另外包括本地数据库的使用方式 ...

随机推荐

  1. java基础解析系列(十一)---equals、==和hashcode方法

    java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...

  2. struts2 maven整合tiles3

    最新项目发现使用tiles能够很好的将多个页面组合起来,以下就是配置信息,使用tiles3 1.首先配置maven pom.xml加入例如以下: <dependency> <grou ...

  3. 关于系统首页绘制问题(ext布局+c#后台加入数据)经html输出流输出响应client

    关于系统首页绘制问题,业务需求 TODO 绘制系统首页(Main.aspx) 採用的技术:functioncharts+jquery+ext布局+c#+html 解说篇:1,服务端aspx,2,服务端 ...

  4. x86 处理器开机顺序

    无论是千万行的linux ,还是百万行的uefi ,或者百十行的app, 它都有一个主线.应用程序是main() 函数里面全部函数运行完,程序结束.这里main() 做为程序的起点,uefi 能够觉得 ...

  5. 入门Webpack

    ---恢复内容开始--- 什么是WebPack,为什么要使用它? 为什要使用WebPack 现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包.为了简化 ...

  6. 学习Git的最佳资料

    1. ProGit中文版:https://git-scm.com/book/zh/v2 2. 廖雪峰的Git教程: http://www.liaoxuefeng.com/wiki/0013739516 ...

  7. WCF实现长连接

    由于WCF的机制,连接池会在连接建立一定时间后超时,即使设置了超时时间非常长,也可能被服务端系统主动回收.之前做项目时碰到了这个问题,所以项目上考虑采用长连接,自动管理连接池,当连接超时后,自动重建, ...

  8. Centos7安装配置Xhgui

    XhProf是Facebook出品的一个PHP性能监控工具,只包含基本的界面和图形来分析数据.后来Paul Reinheimer在此基础上开发了Xhgui,提供了更好的界面和功能,其主页在https: ...

  9. SignalR简单Demo

    我们实现一个简单的消息通知的Demo 在NuGet中添加SignalR引用 install-package Microsoft.AspNet.SignalR 然后我们创建一个类来引用Hub类 name ...

  10. Android开发——导入github安卓项目源码

    之前在Github上看见其他人的安卓项目源码,便是想下载源码来学习学习,但是下载之后一直导入失败,经过了漫长的摸索终于是成功了,便是分享一下经验 首先进入Github官网,找到想要学习的安卓源码 右上 ...