Neo4j 1.9 中是否有任何方法可以在一定时间内获取所有已修改(创建/更新/删除)的节点/关系 - 就像我们在 SOLR 增量导入中所做的那样?
我能想到的一种粗略的方法是为每个节点/关系维护一个时间戳属性并将它们索引以获取这些节点/关系。
START a=node:custom_index("timestamp:[{start_time} TO {end_time}]")
RETURN a;
但是问题是如果我通过 CYPHER 修改节点,索引将不会更新。
Neo4j 1.9 中是否有任何方法可以在一定时间内获取所有已修改(创建/更新/删除)的节点/关系 - 就像我们在 SOLR 增量导入中所做的那样?
我能想到的一种粗略的方法是为每个节点/关系维护一个时间戳属性并将它们索引以获取这些节点/关系。
START a=node:custom_index("timestamp:[{start_time} TO {end_time}]")
RETURN a;
但是问题是如果我通过 CYPHER 修改节点,索引将不会更新。
不幸的是,在 Neo4j 中没有类似的内置功能。
一一解决问题。维护时间戳是不可能的,因为在删除节点/关系的情况下您无处可去。您也不能在属性上放置时间戳。因此,您会知道节点已更改,但不知道如何更改。
一种可能的解决方案是使用 TransactionEventHandlers 在发生更改时在某处记录更改。然后,您可以 a) 准确选择要记录的内容,并且 b) 不用担心 Cypher,无论您使用什么方法更新数据库,它都会被记录下来。
我整理了一个小演示。它只是将每个更改记录到标准输出。为简单起见,它使用了一些GraphAware类(免责声明:我是作者),但如果您愿意,也可以不使用它们来编写。
这是代码的重要部分,以防链接最终断开或其他情况:
@Test
public void demonstrateLoggingEveryChange() {
GraphDatabaseService database = new TestGraphDatabaseFactory().newImpermanentDatabase();
database.registerTransactionEventHandler(new ChangeLogger());
//perform mutations here
}
private class ChangeLogger extends TransactionEventHandler.Adapter<Void> {
@Override
public void afterCommit(TransactionData data, Void state) {
ImprovedTransactionData improvedData = new LazyTransactionData(data);
for (Node createdNode : improvedData.getAllCreatedNodes()) {
System.out.println("Created node " + createdNode.getId()
+ " with properties: " + new SerializablePropertiesImpl(createdNode).toString());
}
for (Node deletedNode : improvedData.getAllDeletedNodes()) {
System.out.println("Deleted node " + deletedNode.getId()
+ " with properties: " + new SerializablePropertiesImpl(deletedNode).toString());
}
for (Change<Node> changedNode : improvedData.getAllChangedNodes()) {
System.out.println("Changed node " + changedNode.getCurrent().getId()
+ " from properties: " + new SerializablePropertiesImpl(changedNode.getPrevious()).toString()
+ " to properties: " + new SerializablePropertiesImpl(changedNode.getCurrent()).toString());
}
for (Relationship createdRelationship : improvedData.getAllCreatedRelationships()) {
System.out.println("Created relationship " + createdRelationship.getId()
+ " between nodes " + createdRelationship.getStartNode().getId()
+ " and " + createdRelationship.getEndNode().getId()
+ " with properties: " + new SerializablePropertiesImpl(createdRelationship).toString());
}
for (Relationship deletedRelationship : improvedData.getAllDeletedRelationships()) {
System.out.println("Deleted relationship " + deletedRelationship.getId()
+ " between nodes " + deletedRelationship.getStartNode().getId()
+ " and " + deletedRelationship.getEndNode().getId()
+ " with properties: " + new SerializablePropertiesImpl(deletedRelationship).toString());
}
for (Change<Relationship> changedRelationship : improvedData.getAllChangedRelationships()) {
System.out.println("Changed relationship " + changedRelationship.getCurrent().getId()
+ " between nodes " + changedRelationship.getCurrent().getStartNode().getId()
+ " and " + changedRelationship.getCurrent().getEndNode().getId()
+ " from properties: " + new SerializablePropertiesImpl(changedRelationship.getPrevious()).toString()
+ " to properties: " + new SerializablePropertiesImpl(changedRelationship.getCurrent()).toString());
}
}
}