Create unique index in ArangoDB edge collection for multiple path attributes including _from and _to attributes
-
21-12-2019 - |
Question
I am trying to set a unique constraint for an edge collection so that only one edge of a certain type can be created between two given nodes. The issue is that it seems I can't use _from
and _to
attributes as path attributes when creating the index. What I have tried so far:
db._collection('edges').ensureUniqueConstraint('_from', '_to', 'type');
I get the following error:
[ArangoError 10: bad parameter]
I don't want to check whether a certain edge type between two nodes exists before creating it.
Any hints?
Solution
It is currently not possible to create secondary indexes on internal attributes such as _key, _id, _rev, _from, or _to. We want to allow this for a future version of ArangoDB, but it will be a massive code change.
The only way to achieve the desired result is to create an extra attribute in the edge that you save and put the combination of "_from", "_to", and "type" into it. I think these values should be known at edge creation already.
So instead of saving an edge like this
db.edges.save(_from, _to, { type: type, other: ... });
it should be like this:
// create a unique index on attribute "unique"
db._collection("edges").ensureUniqueConstraint("unique");
// create a variable "unique" which contains the values of _from and _to and type
var unique = _from + "-" + _to + "-" + String(type);
// now save the edge, using the "unique" attribute
db.edges.save(_from, _to, { type: type, unique: unique, other: ... });
This is a workaround, but it should solve that particular problem.
OTHER TIPS
Since ArangoDB 3.0 you can ensure uniqueness of relations in edge collections with unique hash index on _from
and _to
fields.
db.edgeCollectionName.ensureIndex({ type: "hash", fields: [ "_from", "_to" ], unique: true });
When a A->B relation exists, another A->B won't be created. B->A can still be created, though.