嵌入式neo4j:迭代一个巨大图的所有节点
embedded neo4j: iterate over all nodes of a huge graph
我想遍历 ~100Mio 图中的所有节点。我知道我可以通过密码查询获取节点
MATCH n RETURN n
但是我必须使用 LIMIT 和 SKIP 来处理数据集,我认为这种方法存在性能问题。
现在我的问题是:如何使用嵌入式 neo4j 数据库遍历所有节点?整个事情将是一个后台工作(将节点索引到 elasticsearch)。
既然你提到你正在使用嵌入式 Neo4j,你可能想使用 Java API 记录 here 而不是 Cypher。
具体来说,class GlobalGraphOperations
提供了一个 getAllNodes()
方法,如记录 here:
for (Node node : GlobalGraphOperations.at(db).getAllNodes()) {
// Do something with the node here
}
编辑
需要考虑的其他几点:
- 您可以实现 transaction hook handler 以在节点 inserted/updated 时启动 Elasticsearch 索引操作,而不是遍历数据库中的所有节点。
- 如果您希望此操作在后台定期 运行,您可能需要考虑使用 GraphAware framework's timer driven runtime module。此插件提供 运行 时间在后台定期执行操作,并且可以配置为随着数据库负载的增加而缩减。
感谢大家提到 GraphAware,只是为了混合使用另一种方法:使用 vanilla GlobalGraphOperations
获取所有节点的问题在于它全部发生在单个事务中。在具有 100M 个节点的图表上,这将不起作用。
出于这个原因,GraphAware Framework has a number of BatchTransactionExecutor
我们在我们的模块中使用重新索引/恢复以及您需要为每个节点/关系或其中的一个子集做一些事情的场景。
让我 post 举例说明如何使用它 - 它来自 GraphAware 的模式执行模块(不是开源的,因此 post 在这里):
final List<String> violations = new LinkedList<>();
new IterableInputBatchTransactionExecutor<>(database, 1000,
new AllNodes(database, 1000),
new UnitOfWork<Node>() {
@Override
public void execute(GraphDatabaseService database, Node input, int batchNumber, int stepNumber) {
for (Constraint<Node> constraint : nodeConstraints) {
if (!constraint.satisfiedBy(input)) {
violations.add(input + " violates " + constraint.toString());
}
}
}
}).execute();
大多数输入参数应该是不言自明的。请注意,AllNodes
是另一个框架 class,它从 database
中以每个事务 1000 个(在本例中)的批次获取所有节点。我们提供其他(AllNodesWithLabel
、AllRelationships
),但您可以轻松实现自己的。
在后台执行此操作就是创建一个单独的线程,或者如果您想变得更复杂,请使用 William 已经指出的框架的定时器驱动模块。
我想遍历 ~100Mio 图中的所有节点。我知道我可以通过密码查询获取节点
MATCH n RETURN n
但是我必须使用 LIMIT 和 SKIP 来处理数据集,我认为这种方法存在性能问题。
现在我的问题是:如何使用嵌入式 neo4j 数据库遍历所有节点?整个事情将是一个后台工作(将节点索引到 elasticsearch)。
既然你提到你正在使用嵌入式 Neo4j,你可能想使用 Java API 记录 here 而不是 Cypher。
具体来说,class GlobalGraphOperations
提供了一个 getAllNodes()
方法,如记录 here:
for (Node node : GlobalGraphOperations.at(db).getAllNodes()) {
// Do something with the node here
}
编辑
需要考虑的其他几点:
- 您可以实现 transaction hook handler 以在节点 inserted/updated 时启动 Elasticsearch 索引操作,而不是遍历数据库中的所有节点。
- 如果您希望此操作在后台定期 运行,您可能需要考虑使用 GraphAware framework's timer driven runtime module。此插件提供 运行 时间在后台定期执行操作,并且可以配置为随着数据库负载的增加而缩减。
感谢大家提到 GraphAware,只是为了混合使用另一种方法:使用 vanilla GlobalGraphOperations
获取所有节点的问题在于它全部发生在单个事务中。在具有 100M 个节点的图表上,这将不起作用。
出于这个原因,GraphAware Framework has a number of BatchTransactionExecutor
我们在我们的模块中使用重新索引/恢复以及您需要为每个节点/关系或其中的一个子集做一些事情的场景。
让我 post 举例说明如何使用它 - 它来自 GraphAware 的模式执行模块(不是开源的,因此 post 在这里):
final List<String> violations = new LinkedList<>();
new IterableInputBatchTransactionExecutor<>(database, 1000,
new AllNodes(database, 1000),
new UnitOfWork<Node>() {
@Override
public void execute(GraphDatabaseService database, Node input, int batchNumber, int stepNumber) {
for (Constraint<Node> constraint : nodeConstraints) {
if (!constraint.satisfiedBy(input)) {
violations.add(input + " violates " + constraint.toString());
}
}
}
}).execute();
大多数输入参数应该是不言自明的。请注意,AllNodes
是另一个框架 class,它从 database
中以每个事务 1000 个(在本例中)的批次获取所有节点。我们提供其他(AllNodesWithLabel
、AllRelationships
),但您可以轻松实现自己的。
在后台执行此操作就是创建一个单独的线程,或者如果您想变得更复杂,请使用 William 已经指出的框架的定时器驱动模块。