Doctrine 2在JSONb字段中加入PK

时间:2019-02-14 13:58:42

标签: doctrine inner-join jsonb

在我们的系统中,我们有用于跟踪事件的表。名为Event的表具有JSONb列source,用于保存对其他表中实体的引用:

| uuid                                 | name                                      | source                                                   |
+--------------------------------------+-------------------------------------------+----------------------------------------------------------+
| 7916c5c9-3af2-41ce-81e4-776847029b08 | App\LoginRequest\LoginRequestExpiredEvent | {"loginRequest": "4dda7873-534d-4c0c-853b-65b4b1056dae"} |

简化的login_request表如下:

| uuid                                 | expireAt            |
+--------------------------------------+---------------------+
| 4dda7873-534d-4c0c-853b-65b4b1056dae | 2019-02-14 08:00:00 |
| 13c85e8c-e2dc-4b3f-aaf5-25920e2c4d04 | 2019-02-14 22:00:00 |

我想选择在事件表中被引用的所有LoginRequest实体。请记住,两个表都没有任何前键关系!仅通过JSONb字段引用LoginRequest。 RAW SQL的工作原理与预期的一样:

SELECT *
FROM login_request AS lr
JOIN event AS ev ON ev.source->>'loginRequest' = text(lr.uuid)

返回结果集,如:

| lr.uuid                              | lr.expireAt         | ev.uuid                              | ev.name                                   | ev.source                                                |
+--------------------------------------+---------------------+--------------------------------------+-------------------------------------------+----------------------------------------------------------+
| 4dda7873-534d-4c0c-853b-65b4b1056dae | 2019-02-14 08:00:00 | 7916c5c9-3af2-41ce-81e4-776847029b08 | App\LoginRequest\LoginRequestExpiredEvent | {"loginRequest": "4dda7873-534d-4c0c-853b-65b4b1056dae"} |

我很难在Doctrine的DQL中获得与RAW SQL相同的功能:

<?php

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\Query\Expr\Join;

class LoginRequestRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, LoginRequestEntity::class);
    }

    public function findExpiredWithEvent()
    {
        $qb = $this->createQueryBuilder('lr');
        $qb
            ->select('lr')
            ->join(
                EventEntity::class,
                'ev',
                Join::ON,
                "ev.source->>'loginRequest' = text(lr.uuid)"
            );

        return $qb->getQuery()->getResult();
    }
}

我无法使JSONb字段道具的JOIN工作。例如,上面的query-builder调用返回异常:

In QueryException.php line 54:

  [Syntax Error] line 0, col 104: Error: Expected end of string, got 'ON'


In QueryException.php line 43:

  SELECT lr FROM App\LoginRequest\LoginRequestEntity lr
  INNER JOIN App\Event\EventEntity ev
  ON ev.source->>'loginRequest' = text(lr.uuid)

是否可以在Doctrine的query-builder中对其他表的JSONb列属性进行JOIN?

1 个答案:

答案 0 :(得分:0)

我有一个类似的sql:

select distinct lru.id, lru.* from tstdf_lru as lru inner join tsrec_failure as failure on failure.lru_id = lru.id inner join wrks_event as event on failure.failure_group_id = (event.data->>'failureGroupId')::BIGINT

也许可以为您提供帮助。