cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Create constraint on propery nodes to not equal each other

Hi all,
I am trying to create a constraint on the property of a node.

CREATE (c:Car {name:'test1', type:'test1'})

I am trying to prevent a user from implementing the name and type property as the same string. (i.e name ≠ type) I also need both properties to be unique using query below.

CREATE CONSTRAINT car_property_1
ON (c:Car)
ASSERT (c.name,c.type) IS NODE KEY 

Also on a curious note can I constraint two different properties on two different nodes to not equal each other also?

1 ACCEPTED SOLUTION

Hi @tarendran.vivekanand,

You could take a look at APOC Triggers to see if they meet the need.

This will allow you to define a check pre-commit with a custom error message, for your example I think the following works

CALL apoc.trigger.add("checkNameType",
"UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, 'name') AS name
with name
UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, 'type') AS type
call apoc.util.validate(name.new = type.new, 'Entry invalid: name (%s) same as type (%s)',[name.new, type.new]) RETURN null", {phase:'before'})

With that enabled you will get an error when trying your CREATE .. statement from above

View solution in original post

11 REPLIES 11

Hello @tarendran.vivekanand

You can add two unique constraints:

CREATE CONSTRAINT car_property_1 ON (c:Car) ASSERT (c.name, c.type) IS NODE KEY 
CREATE CONSTRAINT constraint_name ON (c:Car) ASSERT c.name IS UNIQUE
CREATE CONSTRAINT constraint_type ON (c:Car) ASSERT c.type IS UNIQUE

Regards,
Cobra

@Cobra Sorry my bad didnt double check. The solution you gave me still doesnt take into account whether the property cannot equal to each other. So I have use this query

CREATE (c:Car {name:'test1', type:'test1'})

I should get an error saying u cant set the name and test to be each other

Yeah your right my bad

I don't think it's possible to make it directly but as said here in this topic, you can try their solution to solve your problem

Regards,
Cobra

Thanks anyways. Will just have to figure out another way.

Did you try the solution given in the topic I linked you @tarendran.vivekanand?

However, I can think of a workaround that might be acceptable, depending on your use cases. Let's say you want properties a, b, and c to be unique as a group. You can add an extra property, d, that concatenates the stringified values of a, b, and c, using appropriate delimiter(s) to separate the substrings (such that, for example, the a/b delimiter is a character that never appears in a or b). You can then create a uniqueness constraint on d.

Wont work for me as that is inefficient and will be very costly once you have 100000+ nodes

Ah yeah I see, otherwise you can check before the creation if both properties are different

Yea. Will just have to solve this in FE somehow

Hi @tarendran.vivekanand,

You could take a look at APOC Triggers to see if they meet the need.

This will allow you to define a check pre-commit with a custom error message, for your example I think the following works

CALL apoc.trigger.add("checkNameType",
"UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, 'name') AS name
with name
UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, 'type') AS type
call apoc.util.validate(name.new = type.new, 'Entry invalid: name (%s) same as type (%s)',[name.new, type.new]) RETURN null", {phase:'before'})

With that enabled you will get an error when trying your CREATE .. statement from above

Thank you @stuart.laurie . This saved me so much of work