Delete all relations and connected nodes in Neo4j for a user - neo4j

We have selected neo4j as the DB for our web application. The user has a large number of relations and connected nodes. As of now there are about 20 relations for a user. One of the features is a newsfeed feature. If i want to delete a user completely, is the cypher query the best way to delete or is there any other alternative?
Since we are still planning to add new features, the relationships and nodes connected to the user also will increase. So if we use cypher query, the query has to be modified for every new relationship added. Please advise.
Thanks,
Pavan

Yes, you can use Cypher to remove a user. Of course, there are alternative methods, depending on the language or framework you're using with your web application. If you like to have advise on that, please specifiy how you're using Neo4j in detail.
Note that you have to remove all relationships (outgoing and incoming) first in order to be able to remove the node.
Example:
START n = node(3)
MATCH n-[r]-()
DELETE n, r
This example was taken from the official manual: http://docs.neo4j.org/chunked/milestone/query-delete.html

As of Neo4j 2.3 there is another way to do this:
MATCH (n { name:'Andres' })
DETACH DELETE n
I found this example in the documentation at: http://neo4j.com/docs/stable/query-delete.html

An alternative could be to write a gremlin script that traverses your graph starting with your user and is putting in two collection the relationships and the nodes that you intend to delete. If you want to delete everything, perhaps you can implement your depth first traversal in Gremlin and delete while traversing.

Related

Neo4j Manual Index on Relationship Properties

I'm going to try in my application Neo4j Manual Index on Relationship Properties in order to fix the performance issue I faced Neo4j Cypher query performance optimization
I have a few question which is not clear to me from the official Neo4j documentation:
MATCH (:Flight)-[r:DESTINATION]->(:Airport)
CALL apoc.index.addRelationship(r,['taxi_time'])
RETURN count(*)
The statement will create the relationship index with the same name as
relationship-type, in this case DESTINATION and add the relationship
by its properties to the index.
When do I need to create this relationship index? It should be done once(let's say at the application startup) or do I need to invoke this APOC function each time new -[r:DESTINATION]-> relationship is added between Flight and Airport nodes?
In case of existing -[r:DESTINATION]-> relationship update, how to update this information in the appropriate manual index?
In case of deleting some of Flight or Airport node - do I need to manually find and remove appropriate -[r:DESTINATION]-> relationships from the manual index or it will be done automatically by APOC and Neo4j?
In case of Spring Data Neo4j project - how to properly execute queries that contain APOC functions? For example, I want to call apoc.index.addRelationship in order to create the manual index for the relationship properties. Can I use org.neo4j.ogm.session.Session.query for this purpose?
What the consistency model is used for the manual indexes - Do they use eventual consistency or strong consistency model between the index and the original data?
I agree Neo4J documentation on this issue is really insufficient.
To answer your questions:
1.If you upgraded your Neo4J from an older version that used automatic relationship index you would need to run APOC (only once) to index your existing relationships using something like
MATCH ()-[r]->() CALL apoc.index.addRelationship(r,['property_1','property_2']) RETURN count(*);
You would then need to set up a trigger to any new relationship you add to that index, running something like this once:
CALL apoc.trigger.add('RELATIONSHIP_INDEX',"UNWIND {createdRelationships} AS r MATCH ()-[r]->() CALL apoc.index.addRelationship(r,['property_1','property_2']) RETURN count(*)", {phase:'after'})
(you will need to activate apoc.trigger.enabled=true in neo4j.conf file before)
2.See above
3.You would need to remove them also from the index, it is not done automatically. Set up an APOC trigger with removeRelationshipByName() for that.
4.Should be possible.
5.Somebody from Neo4J should answer this.
Hope this helps and saves you some time!

Neo4j - is it possible to visualise a simple overview of my database?

I've got my graph database, populated with nodes, relationships, properties etc. I'd like to see an overview of how the whole database is connected, each relationship to each node, properties of a node etc.
I don't mean view each individual node, but rather something like an ERD from a relational database, something like this, with the node labels. Is this possible?
You can use the metadata by running the command call db.schema().
In Neo4j v4 call db.schema() is deprecated, you can now use call db.schema.visualization()
As far as I know, there is no straight-forward way to get a nicely pictured diagram of a neo4j database structure.
There is a pre-defined query in the neo4j browser which finds all node types and their relationships. However, it traverses the complete graph and may fail due to memory errors if you have to much data.
Also, there is neoprofiler. It's a tool which claims to so what you ask. I never tried and it didn't get too many updates lately. Still worth a try: https://github.com/moxious/neoprofiler
Even though this is not a graphical representation, this query will give you an idea on what type of nodes are connected to other nodes with what type of relationship.
MATCH (n)
OPTIONAL MATCH (n)-[r]->(x)
WITH DISTINCT {l1: labels(n), r: type(r), l2: labels(x)}
AS `first degree connection`
RETURN `first degree connection`;
You could use this query to then unwind the labels to write that next cypher query dynamically (via a scripting language and using the REST API) and then paste that query back into the neo4j browser to get an example set of the data.
But this should be good enough to get an overview of your graph. Expand from here.

Returning on-the-fly relationship in graph form in Neo4j

I'm pretty new to Neo4j and graph DBs in general, and have been playing around with it for the last few days. I've now hit something I'm stumped on: I'm trying to create a "temporary" relationship between two disjoint nodes just for the sake of a RETURN, then not store this relationship within the DB afterwards.
The dataset I'm using is a graph of Movie and Person nodes provided in one of the basic Neo4j built-in tutorials. My query is currently as follows:
MATCH (p1:Person)-[r1:ACTED_IN]-(m1:Movie)-[r2:ACTED_IN]-(p2:Person)
WHERE p1.name="Kevin Bacon"
RETURN {start:p1,rel:"COSTAR",end:p2}
What I'd ultimately like to see is a central "Kevin Bacon" node with COSTAR relationships to a series of Person nodes around it, without any Movie nodes or ACTED_IN relationships being displayed. The query above does show the COSTAR relationship in the returned rows, but it does not appear on the graph itself; I've attached a few screenshots of what I'm seeing.
The only other idea I have is to use the MERGE keyword to create a COSTAR relationship, but (as I understand it) this actually stores the relationship in the DB which is what I'm trying to avoid.
Any suggestions would be greatly appreciated.
The neo4j Browser only visualizes nodes and relationships that actually exist in the DB. So, there is no way to do what you want without actually creating the COSTAR relationships, visualizing the result in the Browser, and then deleting all the COSTAR relationships.
As a workaround you could simply display the nodes of all of Kevin Bacon's costars, like this:
MATCH (p1:Person)-[:ACTED_IN]-(:Movie)-[:ACTED_IN]-(p2:Person)
WHERE p1.name="Kevin Bacon"
RETURN DISTINCT p2;
So you want the relationships to appear in the graph visualization in the Neo4j browser but not store these relationships in the graph itself? I can't think of a way to make that happen (without hacking it), but would deleting the relationships after you are done generating the visual work?
Query to create COSTAR relationships:
MATCH (p1:Person)-[r1:ACTED_IN]-(m1:Movie)-[r2:ACTED_IN]-(p2:Person)
WHERE p1.name="Kevin Bacon"
CREATE UNIQUE (p1)<-[:COSTAR]-(p2);
Execute your query to populate the graph in Neo4j Browser...
Then to delete the COSTAR relationships:
MATCH (:Person)-[r:COSTAR]-(:Person)
DELETE r;
The best way to achieve this (now... 6 years later) is with the gds.graph.create.* functions (assuming you load GDS)
https://neo4j.com/docs/graph-data-science/current/graph-create/
With a graph as simple as this, gds.graph.create(...) would be enough (creating COSTAR for all co-starrings)
Or, if you wanted to do some constraining, gds.graph.create.cypher(...)
The in-memory graph projection feels like what you wanted to achieve - it persists only as long as the DBMS is active, or until you call gds.graph.drop(...)

How to create a new relationship in Neo4j, starting from an existing one, using a Cypher query?

Is there a simple way to create a new relationship in Neo4j, starting from an existing one?
Starting from the actor-director-movie database used in the tutorials, what I would like to do is to get all the {(actor1),(actor2)} couples of nodes in the graph satisfying the relationships:
(actor1)-[:ACTED_IN]->(movie)<-[:ACTED_IN]-(actor2)
and use them to create a new relationship like:
(actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
in whatever direction (I am interested in both directed and undirected graphs).
Is there a way to do this with a simple Cypher query?
Many thanks,
sTe
Using the sample movie dataset:
MATCH (actor1:Person)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(actor2:Person)
WITH actor1, actor2
MERGE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
I'd do that :
MATCH (actor1)-[:ACTED_IN]->()<-[:ACTED_IN]-(actor2)
CREATE UNIQUE (actor1)-[:ACTED_IN_THE_SAME_MOVIE_AS]-(actor2)
which is basically what you said. Relations are uni-directional (no way around), but the api (Cypher queries or Traversal) can read them both ways (so it doesn't really matter which way your create them in some cases).
To check if what you did is ok, you can run the following :
MATCH (actor1)-[:ACTED_IN_SAME_MOVIE]-(actor2)
RETURN actor1, actor2

How can I rename property in the Neo4j web admin application?

I have created a relationship (for example "KNOWS") between 2 nodes on the Neo4j webAdmin application. If I want to rename the relationship (from "KNOWS" to "LOVES"), how can I do it?
The solution I have so far is delete the "KNOWS" relationship and create a new "LOVE" relationship.
Is there any easier way to do this?
Thanks,
Yes, that is how you do it. In the cypher console, you can do
start n=node(1) match n-[r:KNOWS]->m create n-[:FRIEND]->m delete r
see http://tinyurl.com/7umvpro for an example.
If you are using the Embedded neo4j then renaming is not possible. For this, you'll have to delete the existing relationship b/w nodes and then create new relationship b/w same nodes again.
Make sure you all do this in a transaction.
Regards,
Sushil Jain
Click here

Resources