读书笔记——Neo4j实战 数据索引
  5b99XfAwWKiH 2023年11月02日 52 0


Neo4j使用索引以确定在图形数据库中从哪里开始。 在关系数据库中,一个索引提供了通过列的特定数值快速和容易地查找表中的行。 同样,Neo4j的索引使得它通过特定的属性值容易地查找节点或关系。 与关系数据库不同, Neo4j需要应用程序代码创建和维护索引项。因为应用程序的代码负责索引, 所以需要认真考虑索引策略。 关于索引的不明智决策将导致性能低下或硬盘使用超量。

创建和查询索引

创建索引

当做索引的时候, 最常用的是显式创建索引, 然后就像创建节点一样添加索引项。 每一个索引项通常标识一个节点关系属性值。(索引项包含对正在索引的属性具有特定值的一个或多个节点的引用。)

图5-1给出了像这样的节点索引, 可以认为是一个或多个指向节点的指针相关的数值项。 在这种情况下, 我们期望电子邮件地址是唯一的, 因此我们期望对每一个用户有一个主电子邮件地址。

读书笔记——Neo4j实战 数据索引_搜索


在Neo4j中, IndexManager(索引管理器) 使用一个简单的字符串作为索引键提供访问索引。在社交网络的应用中, 通用的起始节点是一个用户。要唯一标识一个用户, 需要用户用自己的电子邮件地址登录。 程序5-1中的代码显示了如何建立一个新用户并建立索引项, 这意味着通过电子邮件地址可以快速地找到代表用户的节点。 在Index接口中定义所有可能的索引操作, 从Neo4j索引管理器部件访问索引的实例如下:

读书笔记——Neo4j实战 数据索引_Neo4j图数据库_02


注意只是简单地以需求的名字向Neo4j索引管理器请求索引。 从代码的角度看, 索引是否存在并没关系, 如果索引不存在, 当有请求时就会建立起来。

读书笔记——Neo4j实战 数据索引_Neo4j图数据库_03


首先, 使用Neo4j核心API创建节点并添加属性 。 其次, 创建索引并将其命名为users——这个名字将成为这个新建索引的唯一标识符。最后, 将节点添加到索引中 。 要添加一个节点到索引中, 需要提供如下三个参数:需要索引的节点(personOne)、索引键(“email”)、索引的值(jsmith@example.org) 。要通过电子邮件查找一个用户, 需要通过以索引的专用名字标识的节点索引获得一个引用, 在本例中, 使用users索引。 然后可以得到一个针对特定的键和值的索引。 程序5-2给出了用电子邮件查找用户节点的示例。

读书笔记——Neo4j实战 数据索引_图形数据库_04


读书笔记——Neo4j实战 数据索引_搜索_05


读书笔记——Neo4j实战 数据索引_Neo4j图数据库_06

索引的键值能引用多个节点值的情况

在前面的例子中, 对每一个用户的邮箱地址进行了索引, 并确保邮箱地址的唯一性。 因此, 索引查找的结果应该是一个邮箱地址。但是不一定都是这种情况。 让我们给用户添加另一个索引属性——年龄。 很显然, 多个用户节点可能会有相同的age属性值。 这需要程序对返回的索引结果进行迭代

读书笔记——Neo4j实战 数据索引_图形数据库_07


读书笔记——Neo4j实战 数据索引_搜索_08


IndexHits(索引结果) 是一次性迭代的, 一旦用过, 就不能再次使用。使用完IndexHits后应该关闭。 如果在所有的结果中迭代(如前面的例子) , IndexHits将会自动关闭。 如果没有迭代所有的索引结果, 必须确保通过调用IndexHits.close() 手工关闭。

索引项的创建并不仅仅是创建和删除。 即使在本章的简单例子中, 也需要处理用户改变他们的邮箱地址或者想要删除他们的账户的情况。因为应用开发者对使用的索引策略非常谨慎, 所以Neo4j并不自动更新由手动做的索引引起的图形数据库本身的数据改变。 后面将会看到如何通过其他一些机制获得这类灵活性的例子, 但是现在我们将重点关注如何处理涉及手动创建索引而引起的变化。

修改索引项

当一个用户想要更改他的邮箱地址时, 将会发生什么情况?所有可能的索引操作都在Index接口定义,而它没有提供更新方法,一旦已经查找过一个索引, 就没有方法对这个已经存在的索引进行修改。解决的方法非常简单: 当处理Neo4j索引时, “先删除后添加”等于“更新”。

读书笔记——Neo4j实战 数据索引_关系数据库_09


通过Index接口的remove方法,对指定节点loggedOnUserNode条目中的邮箱地址项进行删除。通过add方法添加指定节点loggedOnUserNode条目中的邮箱地址项。

索引关系
我们已经了解了如何创建索引项并在图形数据库中快速查找节点, 但是也可以索引节点之间的关系。 这非常像索引节点, 但是使用关系属性作为主键。了解更多有关关系索引可以参见Neo4j手册: http://docs.neo4j.org/chunked/stable/indexing-relationships.html。

自动索引

本章前面讲的是人工创建和维护索引项。 如果你是从关系数据库世界来的, 你将会好奇为什么数据库不能为我们做这项工作。 毕竟, 在关系数据库中, 你只需声明表示哪一列需要索引, 然后让关系数据库在插入、 更新和删除行时维护那个索引即可。Neo4j有两种自动维护索引的方法——模式索引和自动索引, 首先让我
们看一看模式索引。

模式索引 -> 模式索引方法通过节点标签分组索引数据

在2.0版本中, Neo4j引进了模式索引的概念, 从概念上讲, 这与传统的关系数据库使用的索引处理方法很相似。模式索引与节点标签的概念紧密相关,每一个模式索引专门对应着一个标签和一组属性。 例如, 可以对一个用户的姓名属性name定义索引, 或者对电影的名字和出品年份属性year定义索引。你要做的就是定义索引, 因此, Neo4j会负责维护它们

这意味着当创建一个具有标签和属性的节点并匹配一个或多个索引时, 所有的索引都会以那个值进行更新。 当删除一个节点时, 那个节点的所有与相关索引有关的索引项都会被自动删除, 当更新节点关系时也是如此。

读书笔记——Neo4j实战 数据索引_关系数据库_10


这个例子使用了两个标签: 一个是电影, 称为MOVIE, 另一个是用户, 称为USER。现在要定义以后需要的模式索引。 这与在关系数据库中定义索引非常相似。 在图形数据库服务模式(GraphDatabaseService.schema()) 方法中可以使用Java API创建索引。 首先, 对name属性创建MOVIE标签索引,然后对USER标签进行同样的操作 。 定义索引后就可以继续创建节点。 首先为电影Michael Collins创建具有MOVIE标签的节点,因为电影的标签和name属性与早已定义的索引相匹配, 这个节点将自动加到索引中并可以以名字搜索。 下一步, 是为了有趣, 创建一个用户名字为Michael Collins的节点, 与电影的名字相同, 然后提交事务。假设所有的事情都按照计划做完, 那么现在真实期望所创建的节点能被

索引。 可以通过查找电影Michael Collins来证实。 要搜索模式索引, 使用GraphDatabaseService.findNodesByLabelAndProperty方法。 正像名字中所包含的, 这个方法将按指定的标签和属性值搜索所有的节点。在这种情况下, 将搜索与Michael Collins值相匹配的name属性的所有MOVIE标

签。 返回的结果是一个包含匹配节点的Java可迭代集。 这个搜索结果正是所期望得到的那一个。 有两个节点具有相同的名字Michael Collins, 但只有一个具有MOVIE标签, 并且这也就是所期待得到的那个。 每一个节点可以附加一个或多个标签, 每一个标签可以有一个索引。 如果节点具有多个标签, Neo4j将会确保相关的索引按要求更新。

读书笔记——Neo4j实战 数据索引_关系数据库_11


在本例中, 对两个标签做了索引: 一个是常规的用户标签USER, 另一个是管理员标签ADMIN 。 然后创建了单个节点, 使用两个标签代表常规用户和管理员。 我们希望可以通过搜索常规用户或管理员用户找到这个用户, 下面两个步骤正是确认这种情况。删除一个节点时模式索引会更新

读书笔记——Neo4j实战 数据索引_搜索_12

自动索引

要使用自动索引, 需要告诉Neo4j打开节点或关系自动索引, 或两者同时自动索引。 但是, 仅仅是打开自动索引并不会引起任何变化。 在大型数据集中, 索引所有的东西不一定可行, 如果每一个值都在Neo4j内并进行索引,则存储容量将增加两倍或更多倍。 由于维护索引需要额外工作, 每当做一个变更操作时, 也将会使其在性能上降低。 因此, Neo4j对索引采取了更多可选性的方法。 即使在自动索引打开的情况下, Neo4j也将仅仅维护指定索引的节点和关系属性。如何设置自动索引取决于Neo4j的运行模式, 即以嵌入式模式还是以服务器模式运行Neo4j。
在单机运行模式下打开自动索引, 需要以额外的属性修改配置文件。 配置文件在$NEO4J_SERVER/conf/neo4j.properties文件夹中, 需要添加以下两行:

node_auto_indexing=true
relationship_auto_indexing=true

指定要索引什么,需要另外两行:

node_keys_indexable=name, dateOfBirth
relationship_keys_indexable=type,name

在嵌入式模式下打开自动索引, 当创建图形数据库实例时, 需要传递额外的值。 以下的值需要作为一部分包含在java.util.Map的含有配置的参数中:

读书笔记——Neo4j实战 数据索引_关系数据库_13


自动使用设置映射(config map) 需要另外的两个属性, 里面包含需要索引的一列主键名字:

读书笔记——Neo4j实战 数据索引_关系数据库_14


一旦添加了适当的属性配置, 图形数据库将通过自动索引变为可搜索。例如, 假如给定了前面的配置, 图形数据库中的所有关系都具有了type和name属性, 并且图形数据库中所有的节点都有了name和dateOfBirth属性, 这些都可以通过自动索引进行搜索。在配置中没有一种指定索引名的方法, 因此不能在一个索引中指定索引的节点名而在另一个索引中指定索引的出生日期。 这一点与手动索引不同, 在手动索引中总是指定索引的名字。 这是因为Neo4j有一个索引用于关系自动索引而另一个索引用于节点自动索引。下面的程序代码给出打开了具有name主键节点属性的自动索引, 可以以特定的name属性值访问这个索引并使用它查找节点。

读书笔记——Neo4j实战 数据索引_图形数据库_15

Neo4j数据库系列:
​读书笔记——Neo4j实战 使用Neo4jAPI创建节点和关系

读书笔记——Neo4j实战 使用Neo4jAPI 图形遍历

读书笔记——Neo4j实战 数据索引


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
5b99XfAwWKiH