搜索在doctrine中具有多个标记的实体

Asa*_*ara 3 doctrine symfony

我在Document和Tag之间有很多关系.所以一个Document可以有几个Tags,一个Tag可以分配给不同Document的.

这是 Tag

AppBundle\Entity\Tag:
    type: entity
    table: tags
    repositoryClass: AppBundle\Repository\TagRepository
    manyToMany:
        documents:
          targetEntity: Document
          mappedBy: tags
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        label:
            type: string
            length: 255
            unique: true
Run Code Online (Sandbox Code Playgroud)

Document

AppBundle\Entity\Document:
type: entity
table: documents
repositoryClass: AppBundle\Repository\DocumentRepository

manyToMany:
    tags:
      targetEntity: Tag
      inversedBy: documents
      joinTable:
          name: documents_tags
id:
    id:
        type: integer
        id: true
        generator:
            strategy: AUTO
fields:
    title:
        type: string
        length: 255
Run Code Online (Sandbox Code Playgroud)

现在我想搜索具有标签所有文件animalfiction.我如何用学说实现这一目标?

就像是

$repository = $this->getDoctrine()->getRepository('AppBundle:Document');
$query = $repository->createQueryBuilder('d');
$query  ->join('d.tags', 't')
                ->where($query->expr()->orX(
                            $query->expr()->eq('t.label', ':tag'),
                            $query->expr()->eq('t.label', ':tag2')
                        ))
                ->setParameter('tag', $tag) 
                ->setParameter('tag2', $tag2)
Run Code Online (Sandbox Code Playgroud)

不会做的工作,因为它返回要么所有文件tag1tag2.但是andX也不会起作用,因为没有单个标签同时具有两个标签.

use*_*294 8

您可以通过为每个标记添加额外的内部联接来实现此目的:

例:

$em = $this->getDoctrine()->getManager();
$repository = $this->getDoctrine()->getRepository('AppBundle:Document');
$query = $repository->createQueryBuilder('d');
$query->innerJoin('d.tags', 't1', Join::WITH, 't1.label = :tag1');
$query->innerJoin('d.tags', 't2', Join::WITH, 't2.label = :tag2');

$dql = $query->getDql();
$result = $em->createQuery($dql)
    ->setParameter('tag1', 'LabelForTag1')
    ->setParameter('tag2', 'LabelForTag2')
    ->getResult();
Run Code Online (Sandbox Code Playgroud)

也许这个小图片有助于理解这个查询的作用.整个圆圈代表您的所有文件.如果您只使用一个连接,查询将返回绿色+红色或蓝色+红色部分.使用额外的内连接,您将只获得单独看到的连接的交集(这只是红色部分).

在此输入图像描述

如果您还有更多要搜索的标记,则只需添加其他连接即可.