neo4j Cypher create or updating - neo4j

Using Neo 2.0 through REST API /cypher I'm trying to build a rooted tree like structure.
I currently have an indexed start node, I want to attach a unique path of nodes which may already exist. How can I get cypher to create and set or just update if its already in the database but missing certain properties.

Cypher's MERGE command does this, see http://docs.neo4j.org/chunked/milestone/query-merge.html.

I have the same issue currently. I'm looking into CREATE UNIQUE might be what you are after.
http://neo4j.com/docs/stable/query-create-unique.html
edited: actually I think CREATE UNIQUE might be deprecated.

Related

Enforcing the non-existence of relationships in Neo4j

In Neo4j, is there a way of enforcing that a node of a label X is not connected to a node of label Y?
For example, if someone tried to run a query such as:
MERGE (:X)-[:SOME_RELATIONSHIP]->(:Y)
would there be a way to guarantee that such a query would fail?
Thank you!
Neo4j's constraints don't currently support relationship existence or restriction, so you'd need to put in some extra work.
If you have APOC Procedures, you could register a trigger which could get evaluated to check if a relationship being created connects two nodes of those labels and use apoc.util.validate() to generate an error which will fail and rollback the transaction.
If you want to do this without APOC, it's a bit more work, as you'll need to create a TransactionEventHandler, and then a kernel extension to load your event handler. Here's a blog entry on this approach.

How to use Structr platform to add a new node to an existing relationship?

I am new to Neo4j and I want to add a new node to an existing relationship using Structr platform.
This is the Cypher query that I tested in Neo4j web browser and it works.
match(projects:Project {name:'IRIS Recognition Java'})
create(client:Client {name:'Andreas Pal'}) CREATE(projects)-[w:IS_PART_OF]->(client)
return w
In the Structr platform I created a table that contains all the existing projects from database and I want to assign a member to the project.
I tried to put in a table date a query to bring also the clients. And I don't know how to create the assign. Any help would be very much appreciated. Thank you.
You need to use Structr's means of editing the data in the database. If you use Cypher directly, you are modifying the data on a different (wrong) level. You can either use Structr directly to create relationships, or you have to make the relationships in a way that Structr can detect and "see" those relationships.
Please have a look at https:/support.structr.com/article/295 for more information.

How to implement composite constraint or the equivalent of "is node key" in neo4j ogm?

I'm using Neo4j OGM version 2.1.3.
I used to have a #Index (unique=true, primary=true) on a specific attribute and things worked fine when session.save(obj) was executed.
It was correctly able to execute either a CREATE or a MERGE based on the unique constraint. However, now I need a composite constraint that spans 3 different attributes.
Since I couldn't find a means to specify a composite index using OGM, I've specified a IS NODE KEY constraint on those 3 properties/attributes outside of code (directly executing a CYPHER on Neo4j shell).
Now, after adding a relationship when I try to execute a session.save(domainObj), I now get a Node already exists with ... exception since ogm tries to execute a CREATE query instead of a MERGE.
How do I provide a hint to OGM to not construct a CREATE but a MERGE ?
Or in other words, is there a way to specify a composite constraint in OGM so that I can get past this issue?
Unfortunately this is not currently supported (neither in neo4j-ogm 2.1.x nor upcoming 3.0.0).
Please feel free to create a feature request at https://github.com/neo4j/neo4j-ogm/issues.

Neo4j nodes or relationship supports ttl?

I am learning neo4j , i want to know that is there any way that i can create a relationship or a node that will be delete automatically after a certain period of time.
As pointed out by #Scott in the comments, you can specify a TTL on nodes by using APOC as shown here. Append the following to your neo4j.conf:
apoc.ttl.enabled=true
Then you can either set the appropriate label and property yourself:
SET n:TTL
SET n.ttl = timestamp() + 3600
or utilize one of the following procedures:
// Expires in
CALL apoc.date.expire.in(node,time,'time-unit')
// Expires at
CALL apoc.date.expire(node,time,'time-unit')
There's nothing that I know of like this. Neo4j is just a database like *SQL or MongoDB (though let me know if they can do something like this).
The best suggestion that I would have is to put a delete_after property (or something similar) on the relationships and then have a job which queries on a regular basis to clean them up. Note that you can't query for relationships directly (that is, nodes always need to be involved in your query) so depending on how big your database is, you may need to think through what sort of index you need. I'm a bit vague here because I don't know what your domain model would look like.
If you are like me and stumble to this article, this has recently been updated.
Ref: https://neo4j.com/labs/apoc/4.3/overview/apoc.ttl/apoc.ttl.expireIn/
Match(person:person {id: 100})
CALL apoc.ttl.expireIn(person, 10,'s')
Return person;
Another option for Neo4j is using a Neo4j extension by GraphAware: neo4j-expire
One disadvantage of using such extensions is sometimes they stop supporting them for newer versions of Neo4j and also it takes some time for them to support the latest version. If these things are not a problem with you, you should have no problem with the extension.

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

Resources