Поиск нескольких столбцов с помощью Doctrine Query Builder - PullRequest
1 голос
/ 13 октября 2019

У меня есть столбцы, которые содержат записи следующей формы:

col1    |   col2 |   col3
dog         123      bunny
cat         456      table
bunny       789      laptop

, и у меня есть поисковый запрос. Предположим, что это bunny, тогда я хотел бы вернуть все строки, содержащие слово bunny в любом из своих столбцов. В этом случае это были бы строки 1 и 3.

Все столбцы имеют форму:

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $col1;

Я все еще новичок в построителе запросов доктрины, поэтому мне сложноначать, но я думаю, что это должно быть что-то вроде следующей формы (но, возможно, я упрощаю это):

        foreach ($this->columns as $column)
        {
            // the problem is my columns don't have the entry property nor do I have the $row as an object
            $queryBuilder->andWhere($this->searchTerm = $column.entry)->select($row)
        }

Так что я немного застрял и запутался, как на самом деле получить запись строкии как только он совпадет с searchTerm, чтобы вернуть записи других столбцов в этой строке. Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 14 октября 2019

LIKE поиск будет работать, просто они, как правило, намного медленнее, потому что им нужен доступ к строке, а не к индексу. Использование подстановочных знаков с обеих сторон компаратора гарантирует, что он не будет использовать индекс с LIKE ^.

Однако, если вы сделаете поле FULLTEXT доступным для поиска, вы получите лучшие инструменты поиска, включая сопоставление подстрок. MySQL после 5.6 позволяет также использовать FULLTEXT на InnoDB.

Заимствование из ответа Фрэнка Б. Вот что-то похожее. Не забудьте также запустить

bin/console d:s:u --force

.

/**
 * @Entity
 * @Table(indexes={
       @Index(name="search_idx", flags={"fulltext"}, columns={"col1", "col2", "col3"})
   })
 */
class SomeEntity
{

...

class SomeEntityRepository
{
    public function search($searchTerm)
    {
        return $this->createQueryBuilder('r')
            ->where('MATCH(col1, col2, col3) AGAINST(:term IN NATURAL LANGUAGE MODE')
            ->setParameter('term', $searchTerm)
            ->getQuery()
        ;
    }

...

^ Если термин имеет подстановочный знак только справа ('brown %'), может использовать индекс для LIKE.

1 голос
/ 13 октября 2019

Примерно так в вашем классе репозитория.

public function search($searchTerm)
{
    return $this->createQueryBuilder('r')
        ->where('r.col1 LIKE :term OR r.col2 LIKE :term OR r.col3 LIKE :term')
        ->setParameter('term', '%' . $searchTerm . '%')
        ->getQuery()
    ;
}

и добавьте аннотацию к вашей сущности, чтобы добавить индекс к вашим столбцам:

/**
 * @Entity
 * @Table(indexes={@Index(name="search_idx", columns={"col1", "col2", "col3"})})
 */
class SomeEntity
{
}

И используйте CLI дляизменения в вашей базе данных

php bin / console доктрина: схема: обновление --force

...