0

我需要一些帮助来决定我的 Neo4j 数据库的正确索引策略。在数据库中,我有拥有项目的用户,每个用户和项目都有一个修改的纪元整数值和一个 UUID 值(一个修剪过的 Base64 字符串)。我正在 2.0-M6 上进行开发,因此我可以很好地使用基于新模式的索引来查询标签 USER 的“uuid”字段上的用户。

但是索引用户的项目更复杂。我想做“userUUID=X AND modified > Y”类型的两个查询,它应该返回所有修改整数大于(更新)比数字 Y 的项目。但我也想做一个简单的搜索“userUUID=X, itemUUID=Z”,应该返回单个节点。

  1. 在我目前对 Lucene 的非常有限的理解中,最好的解决方案可能是一个具有三个键“userUUID, itemUUID, modified”的索引,这将允许我使用复合查询来查询它。但是我将如何创建这样一个索引,并且随着我的用户群的增长它会保持快速吗?索引应该主要在 userUUID 属性上进行优化,该属性在每个查询中,并且仅在 itemUUID 和修改后的整数上进行。那可能吗?

  2. 另一种选择是为每个用户为修改后的值建立一个索引,然后为直接项目访问建立一个带有连接键“userUUID+itemUUID”的索引。这比选项 1 更容易实现,因为 Neo4j 很好地支持和记录了单个键索引。但是如果我说有一百万用户,索引“modified-items-for-X”的索引查找是否仍然很快,并且所有这些索引会占用我所有的内存吗?

这个问题是相关的,但是Lucene indecies 的数量要少得多。

编辑。正如 Stefan 猜测的那样,用户和项目通过 OWNS 关系链接在一起,并且 UUID 对于数据库中的每个节点都是唯一的。

为了进一步澄清,我正在寻找查询项目的最高性能解决方案:单个用户预计有数千个项目,并且每个用户将以稳定的速度发出“userUUID=X AND modified > Y”查询(甚至每分钟一次),“userUUID=X and itemUUID=Y”查询也是如此。所以这里的每一毫秒都很重要。

4

2 回答 2

1

在 Neo4j 2.0 架构索引仅限于单个属性,但您可以为每个标签创建多个索引。我假设您正在使用标签User,并且您的用户与他们的项目Item有关系。OWNS进一步的假设是 uuid 确实是唯一的,并且不被多个节点共享。在这种情况下,我不会索引该modified属性。uuid 上只有一个索引:

CREATE INDEX ON :User(userUuid)
CREATE INDEX ON :Item(itemUuid)

请记住:索引应该用于查找遍历的起点。

使用 use查找用户 X 的所有项目modfied > y

MATCH (user:User)-[:OWNS]->(item:Item)
WHERE user.userUuid={X} and item.modified > {Y]
RETURN item

要查找特定项目,只需:

MATCH (item:Item) 
WHERE item.itemUuid={uuid}
RETURN item

如果你真的需要复合索引,你可以使用遗留索引——但模式索引更舒服。

另请注意,在撰写本文时,2.0 是一个里程碑版本,这意味着它还没有准备好生产。

于 2013-10-26T18:19:48.260 回答
0

为了将来参考,我最终选择了选项 1,并为项目创建了一个三键索引(在 Scala 中):

val itemsIndex = neo4j.gds.index().forNodes("items")
itemsIndex.add(itemNode, "user", userUUID)
itemsIndex.add(itemNode, "item", itemNode.getProperty("uuid"))
itemsIndex.add(itemNode, "modified", new ValueContext(getProperty("modified").asInstanceOf[Long] ).indexNumeric())

然后查询它:

itemsIndex.query( "user:\"" + userUUID) + "\" AND item:\"" + itemUUID)+ "\"")
于 2013-11-14T09:17:47.777 回答