如何根据 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