मैं एक तरह से 2 संबंधों में शामिल होने की कोशिश कर रहा हूं। यह काफी काम नहीं कर रहा है जैसा कि मैंने उम्मीद की थी। मैं इसमें सही हो जाऊंगा क्योंकि कोड को पढ़ना आसान है।

class Video
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * Many Videos have Many Tags.
     * @ORM\ManyToMany(targetEntity="App\Entity\Tag", inversedBy="videos")
     * @ORM\JoinTable(name="video_tag")
     *
     * @Assert\Valid
     */
    private $tags;

    /**
     * Many Videos have Many Categories.
     * @ORM\ManyToMany(targetEntity="App\Entity\Category", inversedBy="videos")
     * @ORM\JoinTable(name="video_category")
     *
     * @Assert\Valid
     */
    private $categories;

    ...
}

class Tag
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * Many Tags have Many Videos.
     * @ORM\ManyToMany(targetEntity="App\Entity\Video", mappedBy="tags")
     */
    private $videos;

    ...
}

class Category
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * Many Tags have Many Videos.
     * @ORM\ManyToMany(targetEntity="App\Entity\Video", mappedBy="categories")
     * @Assert\NotBlank
     */
    private $videos;

    ...
}

यहां 3 टेबल शामिल हैं: Video Tag और Category

एक Video में कई Tag और कई Category हो सकते हैं। जबकि Tag और Category कई Video से संबंधित हो सकते हैं।

जंक्शन तालिकाओं का उपयोग करके बहुत से मानक कई सेटअप।

मैं ठीक से काम करने के लिए एक उन्नत खोज फ़ॉर्म प्राप्त करने का प्रयास कर रहा हूं। समस्या तब होती है जब मैं क्वेरी में LIKE जोड़ता हूं।

यहाँ लंबे संस्करण हैं:

  if(isset($data['ti']) && !empty($data['ti'])) {
        $qb->andWhere('v.title LIKE :title');
        $qb->setParameter(':title', '%' . str_replace('%', '', $data['t']) . '%');
    }

    if(isset($data['t']) && !empty($data['t'])) {
        if(stristr($data['t'], ',')) {
            $tags = explode(',', $data['t']);
            $tags = array_filter(array_map('trim', $tags));

            $qb->leftJoin('v.tags', 'tags')
                ->andWhere('tags.name IN (:tags)');
            $qb->setParameter(':tags', $tags, Connection::PARAM_STR_ARRAY);
        }
    }

    if(isset($data['c']) && !empty($data['c'])) {
        if(stristr($data['c'], ',')) {
            $categories = explode(',', $data['c']);
            $categories = array_filter(array_map('trim', $categories));

            $qb->leftJoin('v.categories', 'categories')
                ->andWhere('categories.name IN (:categories)');
            $qb->setParameter(':categories', $categories, Connection::PARAM_STR_ARRAY);
        }
    }

    if(isset($data['u']) && !empty($data['u'])) {
        if(strtolower($data['u']) === 'asc') {
            $qb->addOrderBy('v.createdAt', 'ASC');
        } else {
            $qb->addOrderBy('v.createdAt', 'DESC');
        }
    }

    if(isset($data['v']) && !empty($data['v'])) {
        if(strtolower($data['v']) === 'asc') {
            $qb->addOrderBy('v.views', 'ASC');
        } else {
            $qb->addOrderBy('v.views', 'DESC');
        }
    }

    if(isset($data['d']) && !empty($data['d'])) {
        switch (strtolower($data['d'])){
            case 'any':
                break; // any duration is acceptable
            case '60_180':
                $qb->andWhere('v.duration >= 60');
                $qb->andWhere('v.duration <= 180');
                break;
            case '180_360':
                $qb->andWhere('v.duration >= 180');
                $qb->andWhere('v.duration <= 360');
                break;
            case '360_540':
                $qb->andWhere('v.duration >= 360');
                $qb->andWhere('v.duration <= 540');
                break;
            case '540_720':
                $qb->andWhere('v.duration >= 540');
                $qb->andWhere('v.duration <= 720');
                break;
            case '720_900':
                $qb->andWhere('v.duration >= 720');
                $qb->andWhere('v.duration <= 900');
                break;
            case '900_999999':
                $qb->andWhere('v.duration >= 900');
                break;
        }
    }

और संक्षिप्त अधिक पुन: प्रयोज्य संस्करण:

$this->createQueryBuilder('v')
    ->andWhere('v.title LIKE :title') // this is the problematic part
    ->setParameter(':title', '%' . str_replace('%', '', $data['t']) . '%')
    ->leftJoin('v.tags', 'tags')
    ->andWhere('tags.name IN (:tags)')
    ->leftJoin('v.categories', 'categories')
    ->andWhere('categories.name IN (:categories)')
    ->addOrderBy('v.createdAt', 'ASC')
    ->addOrderBy('v.views', 'ASC')
    ->andWhere('v.duration >= 60')
    ->andWhere('v.duration <= 180')
    ->getQuery()
    ->getResult(Query::HYDRATE_ARRAY);

और एसक्यूएल ही:

SELECT *
FROM   video v0_ 
       LEFT JOIN video_tag v2_ 
              ON v0_.id = v2_.video_id 
       LEFT JOIN tag t1_ 
              ON t1_.id = v2_.tag_id 
       LEFT JOIN video_category v4_ 
              ON v0_.id = v4_.video_id 
       LEFT JOIN category c3_ 
              ON c3_.id = v4_.category_id 
WHERE  v0_.title LIKE ? 
       AND t1_.NAME IN ( ? ) 
       AND c3_.NAME IN ( ? ) 
ORDER  BY v0_.createdat DESC, 
          v0_.views DESC 

उपरोक्त क्वेरी का परिणाम यह है:

Array()

इस तरह के बिना उपरोक्त क्वेरी का परिणाम यह है:

Array
(
    [0] => Array
        (
            [id] => 1
            [views] => 0
            [title] => Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
            [thumbnail] => 102ec57b8e94bf267b7bc5b348e0ebbc51c0b2f11db10a425f99ef796f293cd1f94147269fd34907.jpeg
            [description] => Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
            [path] => 025a66a75077ab3758d32b7686f96049b47c66f7bf87e98404dadde02b5905871097d59a86707924.mp4
            [isDeleted] => 0
            [slug] => lorem-ipsum-dolor-sit-amet%2C-consectetur-adipiscing-elit%2C-sed-do-eiusmod-tempor-incididunt-ut-labore-
            [createdAt] => DateTime Object
                (
                    [date] => 2019-09-27 17:38:24.000000
                    [timezone_type] => 3
                    [timezone] => UTC
                )

            [duration] => 30
            [md5CheckSum] => d41d8cd98f00b204e9800998ecf8427e
        )

)

यहाँ खोज फ़ॉर्म कैसा दिखता है (यदि यह मदद करता है)

enter image description here


माना जाता है कि मैं एसक्यूएल में बहुत अच्छा नहीं हूं लेकिन मुझे लगता है कि यह काम करेगा। जाहिर है मैं गलत था।

मैं इसे दूसरे तरीके से करने के खिलाफ नहीं हूं। लेकिन यदि संभव हो तो मैं कच्चे एसक्यूएल करने से बचना चाहता हूं।

अगर एक LIKE टाला जा सकता है तो मैं भी इसके साथ ठीक हूं। चूंकि यह बड़े डेटा सेट पर बेहद धीमा है।

किसी भी मदद की सराहना की जाती है।

प्रपत्र से प्राप्त उदाहरण डेटा:

Array
(
[ti] => Lorem
[t] => tag_0,
[c] => category_0,
[u] => DESC
[v] => DESC
[d] => any
)
0
Andrei 28 सितंबर 2019, 09:14

1 उत्तर

सबसे बढ़िया उत्तर

आपके लंबे संस्करण में टाइपो?

if(isset($data['ti']) && !empty($data['ti'])) {
    $qb->andWhere('v.title LIKE :title');
    $qb->setParameter(':title', '%' . str_replace('%', '', $data['t']) . '%');
    //                                                            ^ this should be ti
}
0
Jakumi 28 सितंबर 2019, 10:43