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?

Hello @tarendran.vivekanand :slight_smile:

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

1 Like

@Cobra Thank you :slight_smile:

1 Like

@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 :smile: my bad :slight_smile:

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 :slight_smile:

Regards,
Cobra

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

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 :slight_smile:

Yea. Will just have to solve this in FE somehow :sweat_smile:

1 Like

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

1 Like

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