Negations
Negations can be used to exclude certain subpatterns from your query results - an answer is excluded if it matches the subpattern.
Syntax
not { <pattern> };
The patterns inside a negated is called the excluded pattern.
Like all patterns, negations can be chained, e.g.:
which is equivalent to a negated disjunction Since negations are themselves patterns, they can also be nested, e.g.:
|
Behavior
Negations may appear in match
stages of data pipelines or functions, where they behave as follows.
-
Internal variables. Variable whose scope lies inside an excluded pattern are not returned as part of the stage’s output (i.e., such variables are internal variables).
-
Satisfaction. A pattern with a negation will return those outputs which satisfy the pattern outside the negation, but do not satisfy the excluded pattern for any choice of internal variables in that pattern.
-
Recursion. When using recursive functions with negations, care needs to be taken that evaluation of the negation does not depend on the recursive function call itself (in other words, TypeDB works with stratified negation).
Examples
Schema for the following examples
#!test[schema, commit]
define
attribute email, value string;
attribute phone, value string;
attribute username, value string;
relation friendship, relates friend @card(0..2);
relation marriage, relates spouse @card(0..2);
relation policy, relates covered @card(0..);
entity user,
owns username, owns email, owns phone,
plays friendship:friend;
entity person, plays marriage:spouse, plays policy:covered;
-
Retrieve users without friends
#!test[read] match $x isa user, has username $name; not { friendship($x, $y); };
-
Retrieve users without friends that have no friends
#!test[read] match $x isa user, has username $name; not { friendship($x, $y); not { friendship($y, $z); }; };
Negated queries (especially nested negations) can become expensive.