Удалить специальные символы с доктриной - PullRequest
0 голосов
/ 05 ноября 2019

Я выполняю поиск, чтобы найти город в своей базе данных, когда я набираю "Aulnay-sous-bois" без проблем, я не могу найти нужный город, но когда я набираю "Aulnay sous bois", он не работает!

Я уже пытался удалить символы, но он не работает

мой контроллер кода:

public function verifyCity(Request $request, CityRepository $cityRepository): JsonResponse
    {
        if($request->isXmlHttpRequest()) {
            $data = [];
            $searchs = $cityRepository->findBySearchCity($request->request->get('city'));
            /**
             * @var $searchs City[]
             */
            foreach ($searchs as $search) {
                $data[] = [
                    'name' => $search->getName(),
                    'zipCode' => $search->getZipCode()
                ];
            }

            return new JsonResponse(['city' => $data, 'ok' => 1]);
        }
        return new JsonResponse(['error' => 'not found']);
    }

мой репозиторий

public function findBySearchCity($search,$zipCode = null)
    { //SELECT * FROM `city` WHERE name LIKE "%la courn%" OR zip_code LIKE "78%"
         $query =$this->createQueryBuilder("c")
            ->where('c.name LIKE :search')
            ->setParameter('search', "%".$search."%");
         if($zipCode != null) {
             $query->orWhere('c.zipCode LIKE :zipCode')
                 ->setParameter('zipCode', $zipCode."%");
         }
         return $query->getQuery()->setMaxResults(5)
             ->getResult();

    }

и Js:

   var cityTabs = [];
    $('#registration_form_city').keyup(function () {

        var city = this.value;
        var data = {
            city: city,
        };
        $.ajax({
            url: $('#wizardProperty').attr('data-verify-city'),
            type: 'POST',
            data: data,
            dataType: 'JSON',
            success: function (data) {
                cityTabs = [];
                if(data.ok == 1) {
                    $.each(data.city,function (k, v) {
                        cityTabs.push(v.name);
                    });
                }
                console.log(cityTabs);
                $( "#registration_form_city" ).autocomplete({
                    source: cityTabs
                });
            },
            error: function (data) {
                console.log(data)
            }
        });
    });

как объяснено выше, когда я печатаю точно с черточками, это работает, но когда я печатаю без черточки, это больше не работает, как отображать результаты, удаляя "-"

Ответы [ 3 ]

0 голосов
/ 06 ноября 2019

Я предоставлю вам другую альтернативу, используя Полнотекстовый поиск MySQL Функции. Давайте начнем готовить таблицу:

ALTER TABLE city ADD FULLTEXT (`name`);
0 голосов
/ 06 ноября 2019

Исправляя ответ Арли, вот как должен выглядеть запрос:

public function findBySearchCity($search, $zipCode=null) {
    // Can be done in one line with preg_replace()
    // Replace underscore, any white-space and any non-word character with '%'
    $search=preg_replace("/[_\W\s]+/", '%', $search);

    // Always split init from the rest of the query in case you need to use `$qb->expr()`
    $qb=$this->createQueryBuilder("city");

    if($zipCode !== null) {
        $qb->andWhere($qb->expr()->orX(
                $qb->expr()->like("city.name", ":search"),
                $qb->expr()->like("city.zipCode", ":zipCode")))
           ->setParameter('zipCode', $zipCode.'%');
    } else {
        $qb->andWhere($qb->expr()->like("city.name", ":search"));
    }

    $qb->setParameter('search', '%'.$search.'%')
       ->setMaxResults(5);

    return $qb->getQuery()->getResult();
}

Он должен работать следующим образом.
Если это не так, выведите запрос на запрос, обновите свой вопрос им икомментарий здесь.

Советы:

  • Всегда используйте двойные кавычки для вашего запроса. Doctrine будет принимать только одинарную кавычку для строкового значения (одинарная кавычка подходит для параметров).
  • Никогда не используйте where(), всегда начинайте с andWhere() или orWhere()
  • Avoir для использования andWhere() и orWhere() вместе. Предпочитайте expr() ( подробнее здесь )
  • Избегайте смешивать DQL с псевдо-нативным (LIKE, IN и т. Д.) SQL. Доктрина будет жевать вас, если она читает какой-то собственный SQL, который она не может использовать. Вместо этого используйте expr(). Если вы не можете найти то, что вам нужно, в expr(), это означает, что вы должны создать собственный запрос.
  • Полностью назовите свой псевдоним, который впоследствии будет легче читать.
0 голосов
/ 05 ноября 2019

Вы можете изменить значение параметра $search в своем методе хранилища, чтобы заменить тире и пробелы подстановочными знаками %, используя preg_split() и implode().

public function findBySearchCity($search,$zipCode = null)
{ //SELECT * FROM `city` WHERE name LIKE "%la%courn%" OR zip_code LIKE "78%"

    $search = preg_split("/[\s,-]+/", $search);
    $search = implode("%", $search);

     $query =$this->createQueryBuilder("c")
        ->where('c.name LIKE :search')
        ->setParameter('search', "%".$search."%");
     if($zipCode != null) {
         $query->orWhere('c.zipCode LIKE :zipCode')
             ->setParameter('zipCode', $zipCode."%");
     }
     return $query->getQuery()->setMaxResults(5)
         ->getResult();

}

Итак, ваши условия "Aulnay-sous-bois "или" Aulnay sous bois "приведут к запросу, используя:
... LIKE '%Aulnay%sous%bois%'

...