Neo4j Spatial - How To Delete A Node - neo4j

Having successfully created a spatial index, created a node and added it to my index, I'd now like to be able to delete the node (easy) and remove it from the spatial index (not so easy).
At time of writing, the documentation does not cover this.
Looking at the index i can see what to clear up, but on my simple DB i'm not confident if this is a protocol to follow or just a rule of thumb.
My node (within the index) is two "rtree" relationships away from the root of the layer, which i can clean up, if advised to.
Is there an api to delete my node?
If not, is this a good pattern to tidy up the index once i destroy the node in the graph?
Thanks.

When you delete a node it should be automatically removed from any index to prevent orphaned entries. If you experience a different behaviour, I'd consider this being a bug.

Yes, cleaning the index after a node removal is the right thing to do. a PR would be most welcome! Also, make sure removal is idempotent (I believe it already is).

Related

Store a users traversal path through a nested hierarchy

I have a nested tree stored in Neo4j. Where each node can have a (n)-[:CHILD]->(c) relationship with other nodes. Allowing you to query the entire tree from a given node down with MATCH (n)-[c:CHILD*]-(m).
What I am having trouble with, is figuring out how to store a path that a user takes as they walk through a tree. For instance a query to return the path would be (user)-[:USER_PATH*]->(node).
However the path has to remain along the lines of :CHILD relationships, it cannot jump outside of its branch. A user path cannot jump from the leaf of one branch to a leaf of another branch, without first retracting its way back up the path it came from until it finds a fork that will walk down to it.
Also I do not think shortest path will work, because its not the shortest path I want, I want the users actual path. But it should disregard relationships that were abandoned as the user backed out of any branches. It should not be leaving around dead paths.
How would I be able to update the graph after each node is walked to so these rules stay in tact??
It can be assumed that in drilling down into a new branch, it can only step through to one more set of siblings. However all branches it came through are still open, so their siblings can be selected.
Best I can figure is that it needs to:
"prefer" walking the :USER_PATH relationships as long as it can
until it needs to break that path to get to the new node
at which point it creates any new relationships
then delete any old relationships that are no longer on that path
I have no idea how to accomplish that though.
I have spent a ton of time in trial and error and googling to no avail.
Thanks in advance!
Given the image below:
red node = User
green nodes = A valid node to be a new "target"
blue nodes = invalid target node
So if you were to back out of the leaf node it is in currently, it would delete that final :RATIONAL_PATH relation in the chain.
Also the path should adjust to any of the green nodes that were selected, but keeping the existing :RATIONAL_PATH in tact for as far as possible.
Personally I think removing the existing path and creating a new one with shortestPath() is probably the best way to go. The cost of reusing the existing path and performing cleanup is often going to be higher and more complex than simply starting over.
Otherwise, the approach to take would be to match down to the last node of your path, and then perform a shortestPath() to the new node, and create your path.
And then we'd have to perform cleanup. This would probably involve matching all paths along :RATIONAL_PATH relationships to the end node resulting in a group of paths. The one with the shortest distance is going to be the one we keep. We'd need to collect those relationships, collect the other relationships of other paths that are no longer valid, do some set subtraction to get the relationships not used in the shortest path, and deleting them.
That's quite a bit of work that should probably be avoided.

Cypher: Creating a schema index that already exists

When you ask Neo4j to create an index that already exists it does not thrown an exception, which seems good for my purpose.
session.run("CREATE INDEX ON :User(email)");
Question 1:
But how is neo4j handling this under the hood? Does it delete the index then recreate it or does it ignore the query altogether since the index already exists?
I'd like to know because I have some CRUD operations and I'd like to define the schema for my nodes at the moment I create them, which means calling "CREATE INDEX" and so fourth. The drawback is this means for every new node created redundant calls to create an index are made, which is fine if they are ignored if the index already exists.
Question 2:
I noticed the following works even if no nodes exist with the label User yet (Meaning I can create labels and index before the associated nodes).
CREATE INDEX ON :User(email)
I'm new to Neo4j and use to the RDBMS world where you can't create an index on a column that does not exist. Am I correct in my belief that creating Indexes and labels before I've even created the nodes that have those labels and properties should not cause any unforeseen problems down the road?
Answering question #2, creating indexes and constraints even when no nodes with those labels or properties exist is perfectly fine, and is in fact an extremely common case. I highly recommend going this route.
I'd recommend against creating indexes with every node creation. While I don't believe it causes much in wasted cycles, it doesn't seem like good design.
Question 1
This won't work if you are creating constraints. They can only be called once and if they exist THEY will indeed throw an exception. Normal indexes don't seem to do so this whole approach should not be attempted.
Question 2
See InverseFalcons comment but it seems to be the correct approach.

What is the best way to mark a deleted Node?

I want to mark node as deleted (and not actually delete the node) and i'm not sure if to set a property in the node(deleted:0/1) or set label to the deleted node. which way is more efficient and right?
From my point of view it's label, because they are indexed by default.
This article could help you - http://graphaware.com/neo4j/2015/01/16/neo4j-graph-model-design-labels-versus-indexed-properties.html
It depends entirely on your use case. In many cases you will actually delete the node. For others you can set a property or add a label. From a performance point of view there shouldn't be much of a difference.
The most important thing is to understand how your application is going to interact with the node that is marked deleted. Do you still want it searchable? How are people searching now and if you don't want it searchable what is the easiest way for you to modify your query to exclude deleted information? Will you ever need to restore the node or query it at a later time?

Creating relationship conditionally with cypher (neo4j)

I am attempting to create a linked list with neo4j, and have a root node with no relationships. Here is the pseudo cypher I am trying to create, but I am not sure how, or even if it is possible:
START root=node(1), item=node(2)
MATCH root-[old?:LINK]->last
WHERE old IS NOT NULL
CREATE root-[:LINK]->item-[:LINK]->last
DELETE old
WHERE old IS NULL
CREATE root-[:LINK]->item
Basically I am trying to insert a node into the list if the list exists, and simply create the first list item otherwise. Obviously you cannot do multiple WHEREs like I have done above. Any ideas how I can achieve this desired functionality with a cypher?
The docs solve the problem by first creating a recurrent :LINK relationship on the root node, but I would like to solve this without doing that (as you then need to create possibly unnecessary relationships for each node).
For anyone interested, I figured out a way to solve the above using some WITH tricks. This is essentially a solution for creating linked lists in neo4j without having to first create a self referencing relationship.
START root=node(1), item=node(2)
MATCH root-[old?:LIST_NEXT]->last
CREATE root-[:LIST_NEXT]->item
WITH item, old, last
WHERE old IS NOT NULL
CREATE item-[:LIST_NEXT]->last
DELETE old
This works by first looking for an existing link relationship, and creating the new one from the root to the item. Then by using WITH we can chain the query to now examine whether or not the matched relationship did in fact exist. If it did, then remove it, and create the remaining link piece from the new item to the old one.
For this, you might want to look at MERGE, http://docs.neo4j.org/chunked/snapshot/query-merge.html#merge-merge-with-on-create-and-on-match
And maybe at the linked list example, http://docs.neo4j.org/chunked/snapshot/cookbook-linked-list.html

Calling Gephi from Ruby on Rails

I'm very interested in building a data visualisation component and can
see how it could be done but would prefer not to reinvent something
which already exists. If this truly is a 'first' then I'm prepared to put my initial code
on Github for others to share [and hopefully improve !!]
Essentially I'd like to be able to do the following:
1) Access a table or tables within a database and create nodes based
on entries within them. Add nodes on create, remove them on delete.
2) Use the foreign keys and/or join tables [for many-many links] to
create edges. Add edge(s) when node created, remove edges when node
deleted, check and add/remove edges when node updated.
3) Pass the nodes and edges to Gephi for display
I can see how to do steps 1 and 2 quickly and easily -- what I haven't
been able to find (after much searching) is how to do step 3.
Has anyone had any success in doing this? -- any example code that they're willing to share ?
Thanks
We tried something similar once, but it may not help you that much. We wrote a Rake task that got data out our DB, which we then fed into Gephi manually. That wasn't really satisfactory and in the end I went with Rake task -> CSV -> R script for visualization (basically connections of users on a world map). If you are not dead set on using Gephi I could show you some of the R code :-)

Resources