如何根据 Symfony 工作流的数组位置过滤对象?
How to filter objects based on the Symfony workflow's place which is an array?
我已经为此苦苦挣扎了一段时间,但找不到一个干净的方法来做这件事,所以我正在寻求一些帮助。
我在数据库 API 输出上有自定义过滤器(ApiPlatform 2.5 和 Symfony 5.1),我需要根据每个输出的当前工作流程位置或状态进行过滤。
Status 具有以下结构,这是 symfony 工作流的地方:
Status = { "OPEN": 1 }
我的问题是状态在数据库中存储为一个数组,我找不到让查询生成器找到匹配项的方法。
我尝试在本地构建一个数组来执行 = 、 LIKE 或 IN :
$status['OPEN'] = 1;
$queryBuilder->andWhere(sprintf('%s.Status = :st', $rootAlias))
->leftJoin(sprintf('%s.Objs', $rootAlias), 'o')
->andWhere('o.Profile = :p')
->setParameters(array(
'st' => $status,
'p' => $profile
));
但是没办法:(
我实施了一个可行的解决方法,但我不喜欢它,因为我经常使用工作流程并且需要一种干净的方法来过滤输出。
我的解决方法非常简单,当状态在数据库中作为数组写入时,我还将它作为字符串存储在另一个名为 StatusText 的字段中,然后在 StatusText 上进行过滤非常简单直接。
状态显然可以有不同的内容:OPEN、CLOSING、CLOSED...
感谢帮助!!
谢谢
编辑和解决方案
按照Youssef的建议,使用scienta/doctrine-json-functions并使用JSON_EXTRACT :
作曲家要求scienta/doctrine-json-functions
重要,这是我的问题的一部分,使用 Doctrine 类型 json_array 一个非数组来存储状态或数据库中的状态,无论您如何称呼它。
集成 ApiPlatform 自定义过滤器中提供的别名:
$rootAlias = $queryBuilder->getRootAliases()[0];
$json_extract_string = "JSON_EXTRACT(".$rootAlias.".Status, '$.OPEN') = 1";
$queryBuilder->andwhere($json_extract_string )
->leftJoin(sprintf('%s.Objs', $rootAlias), 'o')
->andWhere('o.Profile = :p')
->setParameter('p', $profile);
如果 JSON 数组包含状态,您需要询问 Doctrine,但您不能使用 QueryBuilder 方法这样做。
当您遇到 ORM 限制时,您可以使用带有 ResultSetMapping 的本机查询。它允许您使用 DBMS 的特定功能编写一个纯 SQL 查询,但仍然可以获得实体对象。
或者您可以使用 scienta/doctrine-json-functions 并使用 JSON_EXTRACT
我已经为此苦苦挣扎了一段时间,但找不到一个干净的方法来做这件事,所以我正在寻求一些帮助。
我在数据库 API 输出上有自定义过滤器(ApiPlatform 2.5 和 Symfony 5.1),我需要根据每个输出的当前工作流程位置或状态进行过滤。
Status 具有以下结构,这是 symfony 工作流的地方:
Status = { "OPEN": 1 }
我的问题是状态在数据库中存储为一个数组,我找不到让查询生成器找到匹配项的方法。
我尝试在本地构建一个数组来执行 = 、 LIKE 或 IN :
$status['OPEN'] = 1;
$queryBuilder->andWhere(sprintf('%s.Status = :st', $rootAlias))
->leftJoin(sprintf('%s.Objs', $rootAlias), 'o')
->andWhere('o.Profile = :p')
->setParameters(array(
'st' => $status,
'p' => $profile
));
但是没办法:(
我实施了一个可行的解决方法,但我不喜欢它,因为我经常使用工作流程并且需要一种干净的方法来过滤输出。 我的解决方法非常简单,当状态在数据库中作为数组写入时,我还将它作为字符串存储在另一个名为 StatusText 的字段中,然后在 StatusText 上进行过滤非常简单直接。
状态显然可以有不同的内容:OPEN、CLOSING、CLOSED...
感谢帮助!! 谢谢
编辑和解决方案
按照Youssef的建议,使用scienta/doctrine-json-functions并使用JSON_EXTRACT :
作曲家要求scienta/doctrine-json-functions
重要,这是我的问题的一部分,使用 Doctrine 类型 json_array 一个非数组来存储状态或数据库中的状态,无论您如何称呼它。
集成 ApiPlatform 自定义过滤器中提供的别名:
$rootAlias = $queryBuilder->getRootAliases()[0];
$json_extract_string = "JSON_EXTRACT(".$rootAlias.".Status, '$.OPEN') = 1";
$queryBuilder->andwhere($json_extract_string )
->leftJoin(sprintf('%s.Objs', $rootAlias), 'o')
->andWhere('o.Profile = :p')
->setParameter('p', $profile);
如果 JSON 数组包含状态,您需要询问 Doctrine,但您不能使用 QueryBuilder 方法这样做。 当您遇到 ORM 限制时,您可以使用带有 ResultSetMapping 的本机查询。它允许您使用 DBMS 的特定功能编写一个纯 SQL 查询,但仍然可以获得实体对象。 或者您可以使用 scienta/doctrine-json-functions 并使用 JSON_EXTRACT