簡體   English   中英

在IN上查詢Doctrine ManyToMany標簽的關系

[英]Where IN query on Doctrine ManyToMany tags relation

一點背景:

  • 我有Office實體。
  • 辦公室可能有文章。
  • 文章帶有標簽。
  • 辦事處可以與其他辦事處共享標簽(因此可以與文章共享)。

現在,我正在嘗試建立一個查詢,該查詢說:“獲取屬於我的辦公室或具有與我的辦公室共享的標簽的所有文章”。

我已經在MySQL中嘗試過此操作,並且以下查詢按預期工作:

SELECT 
    *  
FROM 
    `articles` `a` 
WHERE 
    (
        `office_id` = 2 
        OR 
        `a`.`id` IN (
            SELECT 
                `at`.`article_id` 
            FROM 
                `article_tags` `at` 
            WHERE 
                `at`.`article_id` = `a`.`id` 
            AND 
                `at`.`tag_id` IN 
                (
                    SELECT 
                        `st`.`tag_id` 
                    FROM 
                        `shared_tags` `st` 
                    WHERE 
                        `st`.`shared_with_id` = 2 
                    AND 
                        `st`.`article` = 1
                )
            )
    ) 
AND 
    `status` = 1

我的實體如下:

文章

/**
 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles")
 * @ORM\JoinTable(name="article_tags")
 * @var ArrayCollection|Tag[]
 */
protected $tags;

標簽

/**
 * @ORM\ManyToMany(targetEntity="Article", mappedBy="tags")
 * @var ArrayCollection|Article[]
 */
protected $articles;

SharedTag

class SharedTag extends Entity
{

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @var int
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Office", inversedBy="sharedTags")
     * @ORM\JoinColumn(name="shared_with_id", referencedColumnName="id")
     * @var Office
     */
    protected $sharedWith;

    /**
     * @ORM\ManyToOne(targetEntity="Office", inversedBy="sharedTags")
     * @ORM\JoinColumn(name="shared_by_id", referencedColumnName="id")
     * @var Office
     */
    protected $sharedBy;

    /**
     * @ORM\ManyToOne(targetEntity="Tag", inversedBy="sharedTags")
     * @var Tag
     */
    protected $tag;

    /**
     * @ORM\Column(type="boolean", options={"default" = 0})
     * @var bool
     */
    protected $template = 0;

    /**
     * @ORM\Column(type="boolean", options={"default" = 0})
     * @var bool
     */
    protected $article = 0;

    /**
     * @ORM\Embedded(class = "\ValueObjects\CreatedAt", columnPrefix=false)
     * @var CreatedAt
     */
    protected $createdAt;

}

那么,如何在DQL或QueryBuilder中對此進行查詢? 我試過幾種方法,但我似乎無法使用tag_id從關系articles.tags在其中()查詢。

先感謝您!


編輯:

經過一番嘗試和錯誤,並感謝Jean的回答,我能夠這樣查詢它:

SELECT
  a
FROM
  Article a
LEFT JOIN a.tags t
LEFT JOIN a.office o
LEFT JOIN o.sharedTags st
WHERE
  (
    a.office = :office
    OR
    (
      t = st.tag
      AND
      st.sharedWith = :office
      AND
      st.article = 1
    )
  )
AND
  a.status.status = :status
AND
  a.template IS NULL
GROUP BY a.id

您應該使用聯接而不是子查詢。 這樣,您將具有更好的性能和更少的DQL代碼:

SELECT DISTINCT `a`
FROM `articles` `a` 
LEFT JOIN `a.tags` `t`
LEFT JOIN `t.shared_with_id` `o`
WHERE (`a`.`office_id` = 2 OR `o`.`id` = 2) 
AND `status` = 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM