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?
To make an index insert the individual array members into the index instead of the entire array value, a special array index needs to be created for the attribute. Array indexes can be set up like regular persistent indexes using the collection. ensureIndex() function.
Primary Index It indexes the documents' primary keys, which are stored in the _key system attribute. The primary index is unique and can be used for queries on both the _key and _id attributes.
Edges in ArangoDB are special documents. In addition to the system attributes _key, _id and _rev, they have the attributes _from and _to, which contain document handles, namely the start-point and the end-point of the edge.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With