I deleted all of node and relationship. Now, I want to delete all existing labels with a Cypher query but I can't.
You are probably referring to the neo4j browser's "Node labels" display. The browser can continue to display labels that have been deleted from all nodes (or even if the DB no longer has any nodes). This is really just a minor nuisance.
As long as your Cypher queries show that there are no nodes with that label, rest assured that the label does not "really" exist in the DB.
If you're removing all of the data (nodes and relationships) anyway, you might as well delete your graph.db directory or wherever you store your data. This will also result in having pre-existing labels not show up in the browser.
This will also remove all indexes you might have had set up.
Related
I've inherited a Neo4j database which is massive to say the least. I've been looking into it and noticed we store a large string in each node that is not used.
Let's say we have a few million nodes called Post and each Post has Text. I'd like to remove Text from each Post in the entire database. Can someone point me down the path of doing so via Cypher?
Also, how would you recommend safely doing this? Should I back up the entire instance incase something goes wrong? Or does Neo4j have a transactional history I can rely on?
Neo4j does not allow NULL in the property so you can REMOVE Text from Post. Here is the syntax:
MATCH (p:Post)
REMOVE p.text
However, you said you have a massive database so I would recommend to remove it by batch.
CALL apoc.periodic.iterate(
"MATCH (p:Post) RETURN p",
"REMOVE p.text",
{batchSize:10000, parallel:true})
It would create batches of 10k Post nodes then remove the property text then run it in parallel.
In any mass updates that you do, it is highly recommended to create a backup of the database.
This code should delete all of the p.text in the nodes that hold it:
MATCH (p:Post)
WHERE exists(p.text)
REMOVE p.text
When I run a query I can see the nodes correctly. But I need to go one by one and click "Expand child relationships" which is tedious and time consuming. Is there any way to see the graph with everything already expanded?
Thanks!
You're talking about Neo4j Browser, right?
If so, you need to specify exactly what you need to visualize first. So let's say you have a User node that is connected to a Book node with a read relationship.
Instead of just
MATCH (u:User)
RETURN u
And expanding that node to see all other connected nodes, just do
MATCH (u:User)-[:read]->(b:Book)
RETURN *
And just add the relationships you want in the query itself.
You can, however, do
MATCH (n) RETURN n
Which will return every node with its relationship, but there's a limit to how many nodes you can see. You can extend the limit in the settings (bottom left of the navigation bar) and tinkering with Graph Visualization values. This is not recommended and, depending on the size of your graphdb, it could cause a bottleneck and it can take a lot of time.
My advice, just write a query that shows exactly which nodes and relationships you want to see.
The Neo4j Browser supports an "auto-completion" mode that, when enabled, automatically queries for (and displays) the relationships between the nodes returned by a Cypher query.
In the most recent versions of the Browser, you can enable auto-completion mode by clicking the gear icon on the left side, scrolling to the bottom of the Browser Settings panel, and check-marking the "Connect result nodes" option.
I used "Match (n) detach delete n" to try delete everything in the graph, but in Neo4j Browser it still shows there is one label and a few properties. That looks like strange.
Please see my attached screenshot. Thanks.
If you have indexes present, the labels and properties used in the indexes will show in the browser. Try looking at :schema.
Also keep note that this is meta data, it isn't necessarily the most accurate reflection of what's actually in your database.
While importing a ton of data from spreadsheets, I attempted to use a labeling convention where nodes were capitalized like "This" and labels for relationships were labeled like "THIS". In one case, I accidentally used the relationship label format for a set of nodes. I then deleted those nodes and reimported them with the correct label format. (Side question - Was there a way to rename a label that I didn't see which could have avoided the delete/reimport?)
My problem is that in the built-in Cypher browser (Neo4j 2.1.3), both the right and wrong labels show up on the node list, even though there are zero nodes with the wrong label. So while I successfully removed the nodes, I can't figure out how to remove the label - not from nodes, which is easy enough using the REMOVE command, but from the database entirely. Why didn't it remove this label automatically when the items it was assigned to reached zero?
To be more specific, I can click on the node label for MEASURES and this query fires:
MATCH (n:`MEASURES`) RETURN n LIMIT 25
with these results:
Returned 0 rows in 77 ms
I would like to completely remove the label 'MEASURES' from the database since nothing is using it. Please let me know if you need further info.
I don't think there is yet a builtin way to remove no-longer-used labels entirely from a neo4j DB. I have also been annoyed by obsolete labels still showing up in places like the neo4j browser web UI.
I know of one way to remove them, but it may not be practical if your DB is enormous, and it might not be totally safe. Therefore, if you choose to do the following, you should make sure you have your original DB backed up (for example, you should make a copy of your original graph.db folder or rename it).
The technique is actually very simple. You just export all the data, shut down neo4j, delete or rename the original graph.db file, restart neo4j, and then re-import the data. The following steps assume that you are in your neo4j installation folder in a linux environment, and neo4j is not running as a service.
Export the data (as CYPHER statements that will recreate the data):
./bin/neo4j-shell -c "dump" > mydump.cql
Shut down neo4j (as it is not safe to remove or rename graph.db while the DB is running):
./bin/neo4j stop
Rename the current graph.db folder, just in case you need to replace the new folder created below:
mv data/graph.db data/graph.db.archive
Restart neo4j, which will automatically create a new graph.db folder:
./bin/neo4j start
Re-import the data from the dump:
./bin/neo4j-shell -file mydump.cql
The obsolete labels should be gone at this point from everywhere (you should reload any neo4j web pages).
Here is how to do it.
What you have to make sure is that
1) no node is using the label
2) and there are no indices or constraints on the label
1) Removing/renaming the label on nodes with a cypher query:
MATCH (n:OldLabel)
SET n:NewLabel /* Optional line if you want to rename the label */
REMOVE n:OldLabel
RETURN n
2a) Check if indices or constraints are using the label using the schema command in the neo4j-shell:
$ neo4j-shell
Welcome to the Neo4j Shell! Enter 'help' for a list of commands
NOTE: Remote Neo4j graph database service 'shell' at port 1337
neo4j-sh (?)$ schema
Indexes
ON :OldLabel(id) ONLINE (for uniqueness constraint)
ON :Person(name) ONLINE (for uniqueness constraint)
ON :Person(id) ONLINE (for uniqueness constraint)
Constraints
ON (person:Person) ASSERT person.name IS UNIQUE
ON (person:Person) ASSERT person.id IS UNIQUE
ON (oldlabel:OldLabel) ASSERT oldlabel.id IS UNIQUE
2b) Remove index and constraint in a cypher query:
DROP CONSTRAINT ON (n:OldLabel)
ASSERT n.id IS UNIQUE;
DROP INDEX ON :OldLabel(id);
Remember to make new indices and constraints if you just wanted to rename the label.
After this the label should no longer show up in the web interface.
Labels don't really exist apart from nodes that use them. You can always query for non-existant labels, and you'll always get zero nodes back.
Here, you're querying for MEASURES and getting nothing. That's pretty much the same thing as the label not existing.
Here's an example with a database I made just now:
$ neo4j-shell -path test
NOTE: Local Neo4j graph database service at 'test'
Welcome to the Neo4j Shell! Enter 'help' for a list of commands
neo4j-sh (?)$ MATCH (m:TotallyNonExistantLabel) return m;
+---+
| m |
+---+
+---+
0 row
1946 ms
So, the bottom line is that you can't really delete labels from your database other than deleting all of the nodes that use them. You can do that like this:
MATCH (f:ThisLabelGonnaDieSucka)
REMOVE f:ThisLabelGonnaDieSucka
RETURN f;
That's basically deleting ThisLabelGonnaDieSucka from the database.
How to delete labels in neo4j? Actually I deleted all nodes and relationships, then I recreated the movie database and still the labels I created before appeared on the webinterface. I also tried to use a different location for the database and even after an uninstall and reinstall the labels still appeared. Why? Where are the labels stored? After the uninstall the programm, the database folder and the appdata folder were deleted.
How to reproduce? Install neo4j -> use the movie database example -> create (l:SomeLabel {name:"A freaky label"}) -> delete the node -> stop neo, create new folder -> start neo -> create movie shema -> match (n) return (n) -> SomeLabel appears, even if you changed the folder or make an uninstall / install.
Is there a way to delete labels even if there is no node with it?
There isn't at the moment (Neo4j 2.0.1) a way to explicitly delete a label once it has been created. Neo4j Browser will display all labels which are reported by the REST endpoint at:
http://localhost:7474/db/data/labels
Separately, the Neo4j Browser sidebar which displays labels doesn't properly refresh the listing when it loses connection with Neo4j. A web browser reload should work.
Lastly, there was a bug in Neo4j Browser's visualization which would display all labels for which a style had been created. If using a version of Neo4j which has the bug, you can clear the styling by clicking on "View Stylesheet" in the property inspector, then clicking the fire extinguisher icon. All of that needs usability improvement, admittedly.
Cheers,
Andreas
This seems to be worked out by version 2.3.0.
As an example, suppose we had created a movie in the data browser such as:
CREATE(m:Movie:Cinema:Film:Picture{title:"The Matrix"})
We could query it with
MATCH(m:Movie)
WHERE m.title = "The Matrix"
RETURN m
It would have 4 labels: Movie, Cinema, Film, and Picture
To remove the Picture label from all movies:
MATCH(m:Movie)
REMOVE m:Picture
RETURN m
To remove the Picture label from only that one movie:
MATCH(m:Movie)
WHERE m.title = "The Matrix"
REMOVE m:Picture
RETURN m
Let us assume that we have created a node Product as below
PRODUCT_MASTER { product_code :"ABC", product_name:"XYX }
CREATE INDEX ON :PRODUCT_MASTER (product_code);
Now even if I delete all PRODUCT_MASTER nodes from graph, we will keep getting PRODUCT_MASTER in browser under Node labels. To get rid of the same , we need to drop the index as well.
DROP INDEX ON :PRODUCT_MASTER (product_code);
In neo4j-shell , type in "schema" command to get the list of indexes and corresponding properties.
To summarize , in case we delete all of the nodes of particular type , you need delete indexes on that node as well .
I simply:
stop neo4j
delete the entire database, and that removes everything
start neo4j
on a mac the db is here
/usr/local/var/neo4j/data/databases/graph.db
The reason is that when a label is created, Neo4j indexes this label. You can delete the node but the index will remain.
At a guess - if you drop the index on the label, it will disappear from the GUI (NOTE- I've not got access to Neo4j at the moment to check this theory)
If you delete the index of that labels, then it will delete the labels from database.
I just found a workaround (with neo4j 2.2 M04). Dump the content of the DB to a file, throw away the DB, then insert the dump again. Only works for small DBs, though.
Step1: dump the content, using neo4j-shell
$NEO4J_HOME/bin/> neo4j-shell -c 'dump match a return a;' > dump.temp
Step2: throw away DB
(there's plenty ways to delete the folder $NEO4J_HOME/data/graph.db/ or wherever your DB folder is)
Step3: insert the dump again, using neo4j-shell
$NEO4J_HOME/bin/> neo4j-shell -file dump.temp
This should bring up statistics on how many nodes, relationships, properties and labels have been created.
(And Step4 would be to delete that dump.temp file, it has no reason to live inside the bin folder.)
What I find odd (and maybe Michael or somebody else from neo4j could shed some light on this): in my case, Step3 told me that some 50+ labels had been created. However, when I open the web interface, only those 15 or so labels, which I actually use, are listed. So the DB feels clean now. Not entirely sure that it is clean.
As of today, with Neo4j Desktop Version: 1.1.10 and DB Version: 3.4.7
Delete data + delete Index + delete any unique constraints + Developer > Refresh clears all Labels