- you use Doctrine MongoDB ODM
- you need some search functionality, that can be expressed through the
QueryBuilder
or theMatchPhase
of the Aggregation Builder - you have a class that holds the search parameters (i.e. a domain class in Symfony)
- you don't want to manually map the search parameters to builder statements
- Search filter class can be any class with public properties
- Properties should be marked with
#[SearchParam]
attribute - Use the
SearchParamParser::parse
with aQueryBuilder|MatchStage
instance to build the query on
class SearchFilter
{
#[SearchParam(type: SearchParamType::String)]
public string $name;
}
Builds the query to:
$builder->field('name')->equals($propertyValue);
class SearchFilter
{
#[SearchParam(type: SearchParamType::Exists, field: 'images')]
public bool $hasImages;
}
Builds the query to:
$builder->field('images')->exists(true);
class SearchFilter
{
#[SearchParam(type: SearchParamType::Int)]
public $age;
}
Builds the query to:
$builder->field('age')->equals((int) $propertyValue);
class SearchFilter
{
/**
* @var int[]
*/
#[SearchParam(type: SearchParamType::IntArray)]
public array $grades;
}
Builds the query to:
$builder->field('grades')->in($propertyValuesAllCastedToInt);
class SearchFilter
{
#[SearchParam(type: SearchParamType::StringEnum)]
public SideOfTheWorldEnum $sideOfTheWorld;
}
Builds the query to:
$builder->field('sideOfTheWorld')->equals($propertyValue->value);
class SearchFilter
{
/**
* @var SideOfTheWorldEnum[]
*/
#[SearchParam(type: SearchParamType::StringEnumArray)]
public array $sidesOfTheWorld;
}
Builds the query to:
$builder->field('sideOfTheWorld')->in($backingValuesOfPropertyValue);
class SearchFilter
{
#[SearchParam(type: SearchParamType::RangeInt, direction: SearchParamDirection::From)]
public int $price;
}
Builds the query to:
$builder->field('price')->gte((int) $propertyValue);
class SearchFilter
{
#[SearchParam(type: SearchParamType::Callable, callable: [SomeClass::class, 'setStatus'])]
public string $status;
}
class SomeClass
{
public static function setStatus(Builder|MatchStage $builder, $value, $filter)
{
// Call $builder methods to build the query
}
}