在Neo4j 1.9中有没有办法获得在一定时间内修改(创建/更新/删除)的所有节点/关系 - 就像我们在SOLR delta导入中那样?
我能想到的一种粗略方法是为每个节点/关系维护一个时间戳属性,并将它们编入索引以获取这些节点/关系 .
START a=node:custom_index("timestamp:[{start_time} TO {end_time}]") RETURN a;
但问题是如果我通过CYPHER修改节点,索引将不会更新 .
遗憾的是,没有像Neo4j那样的内置功能 .
逐一解决问题 . 维护时间戳是不可能的,因为在删除节点/关系的情况下你无处可去 . 您也不能在属性上添加时间戳 . 所以你会知道一个节点已被更改,但不知道如何 .
一种可能的解决方案是使用TransactionEventHandlers在发生更改时将更改记录下来 . 然后,您可以a)准确选择要记录的内容,以及b)不要担心Cypher,无论您使用何种方法更新数据库,都会记录它 .
我把small demo放在一起 . 它只是将每个更改记录到std out . 它使用了一些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()); } } }
1 回答
遗憾的是,没有像Neo4j那样的内置功能 .
逐一解决问题 . 维护时间戳是不可能的,因为在删除节点/关系的情况下你无处可去 . 您也不能在属性上添加时间戳 . 所以你会知道一个节点已被更改,但不知道如何 .
一种可能的解决方案是使用TransactionEventHandlers在发生更改时将更改记录下来 . 然后,您可以a)准确选择要记录的内容,以及b)不要担心Cypher,无论您使用何种方法更新数据库,都会记录它 .
我把small demo放在一起 . 它只是将每个更改记录到std out . 它使用了一些GraphAware类(免责声明:我是作者)以简化,但如果您有这种倾向,可以在没有它们的情况下编写 .
这是代码的重要部分,以防链接最终被破坏或者某些东西: