Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create unique index in ArangoDB edge collection for multiple path attributes including _from and _to attributes

Tags:

arangodb

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?

like image 898
jarandaf Avatar asked Jul 31 '14 08:07

jarandaf


People also ask

How do you ensure individual array members are indexed instead of the entire array?

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.

Which attribute is indexed by the primary index?

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.

What is an edge in ArangoDB?

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.


2 Answers

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.

like image 183
stj Avatar answered Sep 18 '22 05:09

stj


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.

like image 45
mrkvon Avatar answered Sep 20 '22 05:09

mrkvon