简体   繁体   中英

how to search multiple tags in doctrine

I have a database with many-to-many relations on tag and person. I am in trouble when tried to search a person with multiple tags. I tried this but its fail:

        $person = Doctrine_Query::create()
        ->from("Model_Person p")
        ->innerJoin("p.tags t")
        ->whereIn('t.id',$t)
        ->execute();

The above statement return all persons that have at least one of the tags in array $t, but I want only person that havel 'all' the tags on that array.

Anyone know how to achieve this ?

Thanks

This is because IN returns all results with at least one match. Say if you have id IN(1,2,3) it's the same as id = 1 OR id = 2 OR id = 3 .

To archieve your desired goal, use Doctrine's andWhere() method with each value that is now in $t eg [...]->andWhere('id = ?', 1)->andWhere('id = ?', 2)->[...]

After some time of research I found and adopt a pure SQL code which works exactly as I need. In my app rizidoro's person table is info table.

   //$tagQueryString contains tags separated by space ex. "crisis usa"    
   $tagsArray = explode(' ', $tagQueryString);
   $tagsArrayQuery = '"' . implode('","', $tagsArray) . '"';
   //$tagsArrayQuery='"crisis","usa";


    $fromQuery =
            '
        info i
   INNER JOIN (SELECT   it.info_id
               FROM     info_tag it
                        INNER JOIN info i
                          ON i.id = it.info_id
                        INNER JOIN tag t
                          ON t.id = it.tag_id
               WHERE    t.name IN (' . $tagsArrayQuery . ')
               GROUP BY it.info_id
               HAVING   COUNT(it.info_id) = ' . count($tagsArray) . ') ii
     ON i.id = ii.info_id';

    $query = new Doctrine_RawSql();
    $query->select('{i.*}');
    $query->from($fromQuery);
    $query->addComponent('i', 'Model_Info i');

  //you can add offset and limit for pagination
    $infos = $query->limit($resultsPerPage)
                   ->offset($resultsPerPage * ($currentPage - 1))
                   ->execute();

That is not elegant code, but works fine. I have no idea how to do it more "Doctrine-like". Here are other solutions to similar problems: http://www.sergiy.ca/how-to-write-many-to-many-search-queries-in-mysql-and-hibernate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM