无法从Neo4j Spatial索引中删除节点

时间:2016-06-05 22:04:33

标签: neo4j spatial spatial-index

在我的#if USE_X11 // This will make some window managers obey the border being turned on/off. // Most other modern window managers will allow the border to be placed // off-screen: // Unfortunatly stoopid MetaCity raises the window. Sigh CreatedWindow::find(window)->sendxjunk(); # if 1 // Supposedly this tells the new X window managers to put this atop // the taskbar. My tests have shown absolutly zero effect, so this is // either wrong or the window managers are ignoreing it. Newer X // window managers seem to work without this, they probably recognize // attempts to make the window the size of the screen // this method does in fact work, and is used below in my maximize() // so it should probably work here as well // possible problem is that sometimes one have to process/flush events // i.e. by using fltk::wait(1) to have this working // Perhaps below code can be done correctly(?) again - look at maximize() // (or perhaps Im totally wrong, Im new to Xlib ;) --Rafal static Atom _NET_WM_STATE; static Atom _NET_WM_STATE_REMOVE; static Atom _NET_WM_STATE_ADD; static Atom _NET_WM_STATE_FULLSCREEN; if (!_NET_WM_STATE) { # define MAX_ATOMS 30 Atom* atom_ptr[MAX_ATOMS]; const char* names[MAX_ATOMS]; int i = 0; # define atom(a,b) atom_ptr[i] = &a; names[i] = b; i++ atom(_NET_WM_STATE , "_NET_WM_STATE"); atom(_NET_WM_STATE_REMOVE , "_NET_WM_STATE_REMOVE"); atom(_NET_WM_STATE_ADD , "_NET_WM_STATE_ADD"); atom(_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN"); # undef atom Atom atoms[MAX_ATOMS]; XInternAtoms(xdisplay, (char**)names, i, 0, atoms); for (; i--;) *atom_ptr[i] = atoms[i]; } XEvent e; memset( &e, 0, sizeof(e) ); e.type = ClientMessage; e.xclient.window = xid(window); e.xclient.message_type = _NET_WM_STATE; e.xclient.format = 32; e.xclient.data.l[0] = fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; e.xclient.data.l[2] = 0; e.xclient.data.l[3] = 0; e.xclient.data.l[4] = 0; XSendEvent(xdisplay, RootWindow(xdisplay, xscreen), 0, SubstructureNotifyMask|SubstructureRedirectMask, &e); # endif # endif 内部,我试图在成功添加节点后从空间索引中删除节点。但是节点仍然在索引中,我仍然能够使用空间Cypher查询找到它。

这是我的代码的摘录:

TransactionEventHandler.beforeCommit()

这是Neo4j Spatial中的已知错误吗?无论如何,我怎样才能实现我的目标?

PS:我使用的是Neo4j 2.3.2和Neo4j Spatial 0.15-neo4j-2.3.1。

我找到了解决方案(解决方法):

威廉里昂已经阐明了这种情况:

  

使用空间将节点添加到空间索引时   它创建一个代理节点并将该节点添加到IndexProvider接口   空间索引,保持原始节点与   图中RTree索引。

我发现,代理节点始终包含“id”属性。它指向原始节点。我们甚至不需要手动添加它(如William所提出的)。使用它我们可以找到代理节点,以便手动删除它。

有时我们的图表可能如下所示:

enter image description here

有时可能会变得有点复杂:

enter image description here

在图片上:

  1. 空间根(标有“ReferenceNode”标签的节点)标记为“1”
  2. 选择了代理节点
  3. 因此,我们可以使用以下Cypher查询来查找和删除代理节点:

    Index<Node> index = getGraphDatabaseService().index().forNodes("locations", SpatialIndexProvider.SIMPLE_POINT_CONFIG);
    if (node.hasProperty("lat") && node.hasProperty("lon")) {
        index.add(node, null, null); // it works perfectly
    } else {
        index.remove(node); // it doesn't work
    }
    

    以下是我目前在MATCH (:ReferenceNode)-[:LAYER]-()-[:RTREE_ROOT]-()-[*..]-(n {id:{id}}) MATCH (n)-[r:RTREE_REFERENCE]-() DELETE r, n 内使用的完整解决方案:

    TransactionEventHandler

1 个答案:

答案 0 :(得分:1)

使用空间IndexProvider接口将节点添加到空间索引时,它会创建代理节点,并将节点添加到空间索引中,从而使原始节点保持独立来自图中的RTree索引。

这与空间库的其他接口不一致,并引起了一些混淆。有关详细信息,请参阅this SO post

您可以向要编制索引的节点添加id属性,以便在要从索引中删除代理节点时找到代理节点,或者使用空间Java API从空间层添加/删除节点以避免创建代理节点。