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.
type Person {
required property name -> str { constraint exclusive };
multi link friends -> Person {
property strength -> float64;
}
}
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.
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.
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.
insert Person {
name := "Bob",
friends := (
insert Person {
name := "Jane",
@strength := 3.14
}
)
}
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.
edgedb> ....... ....... ....... ....... .......
select Person {
friends: {
name,
@strength
}
};
{ default::Person {name: 'Alice', friends: {}}, default::Person { name: 'Bob', friends: { default::Person {name: 'Alice', @strength: 3.7} } }, }