Light
Dark
System
v2latest
v3dev
v2latest
v1

Using link properties

Links can contain properties. These are distinct from links themselves (which we refer to as simply “links”) and are used to store metadata about a link. Due to how they’re persisted under the hood, link properties have a few additional constraints: they’re always single and optional.

In practice, link properties are best used with many-to-many relationships (multi links without any exclusive constraints). For one-to-one, one-to-many, and many-to-one relationships the same data should be stored in object properties instead.

Let’s a create a Person.friends link with a strength property corresponding to the strength of the friendship.

Copy
type Person {
  required property name -> str { constraint exclusive };

  multi link friends -> Person {
    property strength -> float64;
  }
}
Copy
type Person {
  required property name -> str { constraint exclusive };

  multi link friends -> Person {
    property strength -> float64;
    constraint expression on (
      __subject__@strength >= 0
    );
  }
}

To index on a link property, you must declare an abstract link and extend it.

Copy
abstract link friendship {
  property strength -> float64;
  index on (__subject__@strength);
}

type Person {
  required property name -> str { constraint exclusive };
  multi link friends extending friendship -> Person;
}

The @strength property is specified in the shape of the select subquery. This is only valid in a subquery inside an insert statement.

Copy
insert Person {
  name := "Bob",
  friends := (
    select detached Person {
      @strength := 3.14
    }
    filter .name = "Alice"
  )
}

We are using the detached operator to unbind the Person reference from the scope of the insert query.

When doing a nested insert, link properties can be directly included in the inner insert subquery.

Copy
insert Person {
  name := "Bob",
  friends := (
    insert Person {
      name := "Jane",
      @strength := 3.14
    }
  )
}
Copy
update Person
filter .name = "Bob"
set {
  friends += (
    select .friends {
      @strength := 3.7
    }
    filter .name = "Alice"
  )
};

The example updates the @strength property of Bob’s friends link to Alice to 3.7.

In the context of multi links the += operator works like an an insert/update operator.

To update one or more links in a multi link, you can select from the current linked objects, as the example does. Use a detached selection if you want to insert/update a wider selection of linked objects instead.

Copy
edgedb> 
....... 
....... 
....... 
....... 
....... 
select Person {
  friends: {
    name,
    @strength
  }
};
{
  default::Person {name: 'Alice', friends: {}},
  default::Person {
    name: 'Bob',
    friends: {
      default::Person {name: 'Alice', @strength: 3.7}
    }
  },
}

Specifying link properties of a computed backlink in your shape is supported as of EdgeDB 3.0.

If you have this schema:

Copy
type Person {
  required name: str;
  multi follows: Person {
    followed: datetime {
      default := datetime_of_statement();
    };
  };
  multi link followers := .<follows[is Person];
}

this query will work as of EdgeDB 3.0:

Copy
select Person {
  name,
  followers: {
    name,
    @followed
  }
};

even though @followed is a link property of follows and we are accessing is through the computed backlink followers instead.

If you need link properties on backlinks in earlier versions of EdgeDB, you can use this workaround:

Copy
select Person {
  name,
  followers := .<follows[is Person] {
    name,
    followed := @followed
  }
};
Light
Dark
System