Create first specification¶
Let's create a specification to target users by their name:
use Innmind\Specification\{
Comparator\Property,
Sign,
};
final class SearchByName
{
public static function of(Name $name): Property
{
return Property::of(
'name', //(1)
Sign::equality,
$name, //(2)
);
}
public static function startingWith(Name $name): Property
{
return Property::of(
'name',
Sign::startsWith,
$name,
);
}
}
- This is the name of the property on the
User
class. - The value type must be the same as the one declared on the Aggregate/Entity property.
With this class you can create the rule:
all users whose name is
alice
orbob
or starts with aj
exceptjohn
like this:
SearchByName::of(Name::of('alice'))
->or(SearchByName::of(Name::of('bob')))
->or(SearchByName::startsWith(Name::of('j')))
->and(
SearchByName::of('john')->not(),
);
Targetting entities¶
If you want to target users by city you'd have this specification:
use Innmind\Specification\{
Comparator\Property,
Sign,
};
final class SearchByCity
{
public static function of(string $city): Property
{
return Property::of('city', Sign::equality, $city);
}
}
Depending of the kind of entity you'd use this like this:
address
is the name of the property on User
address
is the name of the property on User
If the aggregate doesn't have an address specified then it won't be matched.
If you only need to know if an entity exist you can use Has
:
Warning
You MUST NOT negate a Just
or a Has
specification as it may not produce the results you'd expect. However you can negate the specification inside the Just
.
This is due to a behaviour inconsistency in Elasticsearch.
Sign::in
¶
When using Sign::in
the value of the specification must be either an array
, a Set
or a Sequence
containing only values of the same type of the property. There MUST be at least one value.