我的安装程序是Symfony 5,运行在PHP7.3上的最新API平台版本。所以我希望能够查询名称和用户名(甚至是电子邮件)。我需要写一个自定义解析器吗?
到目前为止,我已经尝试过了,但结果是WHERE name = $name AND username = $name。
query SearchUsers ($name: String!) {
users(name: $name, username: $name) {
edges {
cursor
node {
id
username
email
avatar
}
}
}
}
我的实体:
/**
* @ApiResource
* @ApiFilter(SearchFilter::class, properties={
* "name": "ipartial",
* "username": "ipartial",
* "email": "ipartial",
* })
*
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="Domain\Repository\UserRepository")
* @ORM\HasLifecycleCallbacks()
*/
class User
{
private $name;
private $username;
private $email;
// ... code omitted ...
}
4条答案
按热度按时间wh6knrhe1#
我为我的tutorial的第6章做了这样一个自定义过滤器。我在下面包括了它的代码。
您可以在ApiFilter标记中配置它搜索的属性。在您的情况下,这将是:
它将搜索字符串拆分为单词,并对每个单词的每个属性进行不区分大小写的搜索,因此查询字符串如下所示:
将在所有指定的属性中搜索LOWER(..)LIKE '%katch%'或LOWER(..)LIKE '%squash%'
限制条件:它可能仅限于字符串属性(取决于DB),并且不按相关性排序。
代码:
服务需要在api/config/services.yaml中进行配置
($searchParameterName实际上可以从@ApiFilter注解中配置)
w1jd8yoj2#
API平台中默认不处理搜索过滤器中的
OR
条件,您需要自定义过滤器来执行此操作(https://api-platform.com/docs/core/filters/#creating-custom-filters)。另请参阅:https://github.com/api-platform/core/issues/2400。
yeotifhr3#
也许你想让客户选择如何合并过滤条件和逻辑。这可以通过在“and”或“or”中嵌套过滤条件来实现,比如:
这将返回用户名中包含“super”或名称中包含“john”的所有用户。或者,如果您需要更复杂的逻辑和同一属性的多个条件:
这将返回名称中包含john且电子邮件地址中包含microsoft. com或apple.com得所有用户.由于嵌套或,说明得条件通过AND与name得条件组合在一起,因此name得条件必须始终为true,而电子邮件得条件中只需有一个为true即可返回用户.
要在您的应用中使用此功能,请在api src/Filter文件夹(如果您还没有此文件夹,请创建此文件夹)中创建一个包含以下内容的FilterLogic.php文件:
然后将以下服务配置添加到api config/services.yml中:
最后像这样调整实体:
您也可以通过添加@ApiFilter注解将其应用到其他类中。
可以通过配置classExp按类名加入/排除过滤器。例如:
将仅在逻辑上下文中应用API平台ORM筛选器
**FilterLogic类的注解是最后一个@ApiFilter注解,这一点很重要。**常规筛选仍将照常工作:过滤器决定如何将其自身应用于QueryBuilder。如果所有用途::andWhere,就像Api Platform的内置过滤器一样,ApiFilter属性/注解的顺序并不重要,但如果某些过滤器使用其他方法,则不同的顺序可能会产生不同的结果。FilterLogic使用orWhere表示“or”,因此顺序很重要。如果它是最后一个过滤器,则其逻辑表达式将成为最上面的表达式,因此定义了主要逻辑。
限制
与Api平台的内置过滤器一起使用,但具有EXCLUDE_NULL的DateFilter除外。This DateFilter子类可能会修复此问题。
假设筛选器创建语义上完整的表达式,即通过::andWhere或::orWhere添加到QueryBundle的表达式彼此不依赖,因此如果通过Doctrine\ORM\Query\Expr\Andx或Doctrine\ORM\Query\Expr\Orx将它们与其他表达式重新组合,则不会危及预期的逻辑。
如果筛选器使用QueryBuilder::where或::add,则可能失败。
建议您检查所有自定义筛选器和第三方筛选器的代码,不要合并使用QueryBuilder::where或::add的筛选器与FilterLogic组合使用,也不要将生成语义不完整的复杂逻辑的筛选器与FilterLogic组合使用。有关语义完整和不完整表达式的示例,请参阅DateFilterTest。
Api Platform IMHO的内置过滤器包含一个与它们生成的JOIN相关的错误。因此,将它们与OR组合并不能像预期的那样对嵌套在to-many和可空关联上的属性起作用。我的FilterBundle提供了解决方法,但它们确实更改了ExistsFilter =false的行为。
vhipe2zx4#
感谢MetaClass和HasBert,它工作得很完美。添加嵌套属性改进的代码