我想遍历~100Mio-graph 中的所有节点。我知道我可以使用 cypher-query 获取节点
MATCH n RETURN n
但随后我将不得不使用 LIMIT 和 SKIP 自己处理数据集,我认为这种方法存在性能问题。
现在我的问题是:如何使用嵌入式 neo4j 数据库遍历所有节点?整个事情将是一个后台作业(将节点索引到弹性搜索)。
我想遍历~100Mio-graph 中的所有节点。我知道我可以使用 cypher-query 获取节点
MATCH n RETURN n
但随后我将不得不使用 LIMIT 和 SKIP 自己处理数据集,我认为这种方法存在性能问题。
现在我的问题是:如何使用嵌入式 neo4j 数据库遍历所有节点?整个事情将是一个后台作业(将节点索引到弹性搜索)。
感谢大家提到 GraphAware,只是为了将另一种方法加入其中:使用 vanilla 获取所有节点的问题GlobalGraphOperations
在于,这一切都发生在一个事务中。在具有 100M 个节点的图上,这不起作用。
出于这个原因,GraphAware Framework有许多BatchTransactionExecutor
我们在我们的模块中使用的 s 用于重新索引/恢复以及您需要为每个节点/关系或其中的子集执行某些操作的场景。
让我发布一个如何使用它的示例 - 它来自 GraphAware 的 Schema Enforcement Module(不是开源的,因此在这里发布):
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();
大多数输入参数应该是不言自明的。请注意,这是另一个框架类,它从每个事务的 1000 个(在本例中)批量中AllNodes
获取所有节点。database
我们提供其他 ( AllNodesWithLabel
, AllRelationships
),但您可以轻松实现自己的。
在后台执行此操作只需创建一个单独的线程,或者如果您想要更复杂,请使用框架的计时器驱动模块,正如 William 已经指出的那样。
由于您提到您使用的是嵌入式 Neo4j,您可能希望使用此处记录的 Java API而不是 Cypher。
具体来说,该类GlobalGraphOperations
提供了一种getAllNodes()
方法,如此处所述:
for (Node node : GlobalGraphOperations.at(db).getAllNodes()) {
// Do something with the node here
}
编辑
需要考虑的其他几点: