Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Neo4j数据库获取增量更改_Neo4j - Fatal编程技术网

从Neo4j数据库获取增量更改

从Neo4j数据库获取增量更改,neo4j,Neo4j,在Neo4j 1.9中,有没有办法像SOLR delta import中那样,在一定的时间跨度内获得所有修改(创建/更新/删除)的节点/关系 我能想到的一个粗略的方法是为每个节点/关系维护一个timestamp属性,并对它们进行索引以获取这些节点/关系 START a=node:custom_index("timestamp:[{start_time} TO {end_time}]") RETURN a; 但问题是,如果我通过CYPHER修改节点,索引将不会更新。不幸的是,Neo4j中没有内置

在Neo4j 1.9中,有没有办法像SOLR delta import中那样,在一定的时间跨度内获得所有修改(创建/更新/删除)的节点/关系

我能想到的一个粗略的方法是为每个节点/关系维护一个timestamp属性,并对它们进行索引以获取这些节点/关系

START a=node:custom_index("timestamp:[{start_time} TO {end_time}]")
RETURN a;

但问题是,如果我通过CYPHER修改节点,索引将不会更新。

不幸的是,Neo4j中没有内置的功能

逐一解决问题。维护时间戳是不可能的,因为在删除节点/关系的情况下,您无处放置时间戳。您也不能在属性上添加时间戳。因此,您可能知道某个节点已更改,但不知道如何更改

一种可能的解决方案是使用TransactionEventHandler将更改记录在某个地方。然后,您可以a)选择要记录的内容,b)不必担心密码,无论您使用何种方法更新数据库,都会记录这些内容

我已经准备好了一份工作。它只是记录每一次对std的更改。为了简单起见,它使用了一些类(免责声明:我是作者),但是如果您愿意的话,也可以不用它们来编写

下面是代码的重要部分,以防链接最终断开或发生其他情况:

@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());
        }
    }
}    
@测试
公共无效演示浏览EveryChange(){
GraphDatabaseService数据库=新的测试GraphDatabaseFactory()。新的无常数据库();
registerTransactionEventHandler(newchangeLogger());
//在这里执行突变
}
私有类ChangeLogger扩展TransactionEventHandler.Adapter{
@凌驾
提交后公共无效(TransactionData数据,无效状态){
ImprovedTransactionData improvedData=新LazyTransactionData(数据);
对于(节点createdNode:improvedData.getAllCreatedNodes()){
System.out.println(“创建的节点”+createdNode.getId()
+具有属性:“+新的SerializablePropertiesImpl(createdNode.toString());
}
对于(节点deletedNode:improvedData.getAllDeletedNodes()){
System.out.println(“已删除节点”+deletedNode.getId()
+具有属性:“+新的SerializablePropertiesImpl(deletedNode.toString());
}
对于(Change changedNode:improvedData.getAllChangedNodes()){
System.out.println(“更改的节点”+changedNode.getCurrent().getId()
+“来自属性:”+新的SerializablePropertiesImpl(changedNode.getPrevious()).toString()
+“到属性:”+新的SerializablePropertiesImpl(changedNode.getCurrent()).toString());
}
for(关系createdRelationship:improvedData.getAllCreatedRelationships()){
System.out.println(“创建的关系”+createdRelationship.getId()
+“节点之间”+createdRelationship.getStartNode().getId()
+和“+createdRelationship.getEndNode().getId()
+具有属性:“+新的SerializablePropertiesImpl(createdRelationship.toString());
}
for(关系deletedRelationship:improvedData.getAllDeletedRelationships()){
System.out.println(“删除的关系”+deletedRelationship.getId()
+“节点之间”+deletedRelationship.getStartNode().getId()
+“和”+deletedRelationship.getEndNode().getId()
+具有属性:“+新的SerializablePropertiesImpl(deletedRelationship.toString());
}
for(changedRelationship:improvedData.getAllChangedRelationships()){
System.out.println(“更改的关系”+changedRelationship.getCurrent().getId()
+“节点之间”+changedRelationship.getCurrent().getStartNode().getId()
+和“+changedRelationship.getCurrent().getEndNode().getId()
+“来自属性:”+新的SerializablePropertiesImpl(changedRelationship.getPrevious()).toString()
+“到属性:”+新的SerializablePropertiesImpl(changedRelationship.getCurrent()).toString());
}
}
}    

谢谢Michal,但有了它,我需要维护另一个系统,在这个系统中,所有这些更改都将被删除,并从中查询。我要找的是,给我所有已更改的节点ID,以便我可以处理它们。小心节点ID,它们是可回收的。因此,当您删除一个节点时,其ID最终将分配给另一个节点。您应该使用自己的标识符。至于维护一个不同的系统,这是一个选择。其他选项包括将更改发布到消息队列或文本文件,或将其存储在图形中的某个位置(注意,如果更改位于一个位置,则它将成为锁的热点)…您可以拥有节点的链接列表,即由事务事件处理程序管理的事件列表@MichalBachman关于争用,在任何给定的时间,无论如何只有一个线程可以提交,因此,如果只有处理程序写入该队列,那么它将不会成为其他事情的瓶颈。嗨,Mattias,关于争用,我说的是一个场景,例如,您可以将每个更改的节点链接到具有已更改关系的根节点。在这种情况下,每个tx都会尝试锁定根节点,从而导致多线程环境中的吞吐量降低。对吗?谢谢。关于你的解决方案,这肯定是一个选择,但我想它不会在重启后继续存在。