Как реализовать поиск Soundex (в MySql) с помощью Doctrine и Symfony 3

Нечеткий поиск — очень важная особенность поисковых систем. Вы можете реализовать нечеткий текстовый поиск в базе данных MySQL, используя комбинацию встроенных пользовательских функций, таких как сопоставление и т. Д.

Чтобы сопоставлять результаты даже с ошибочно введенным вводом, мы можем использовать встроенную функцию MySQL SOUNDEX, чтобы перехватывать их. В этой статье вы узнаете, как реализовать использование Soundex для доктрины в проекте Symfony.

Замечания: Этот учебник работает как для Symfony 2.x, так и для Symfony 3.x.

Реализация

Чтобы начать, найдите себя в корневой папке вашего пакета и создайте папку с именем Extensions (или корневой каталог /src), затем создайте папку внутри с именем Doctrine. Создайте внутри папки доктрины новый класс с именем SoundexFunction.php и сохраните следующий код внутри.

Не забудьте изменить пространство имен в соответствии с расположением внутри вашего проекта.

match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringExpression = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'SOUNDEX(' .
$this->stringExpression->dispatch($sqlWalker) .
')';
}
}

Класс позволит вам использовать оператор SOUNDEX в наших запросах без каких-либо ошибок, таких как:

[Ошибка синтаксиса] Ошибка: ожидаемая известная функция, получил «SOUNDEX»

Сейчас класс существует в нашем проекте, но он не зарегистрирован. Чтобы использовать его, нам нужно зарегистрировать функцию в config.yml файл нашего проекта, просто перейдите в область доктрины и сохраните SOUNDEX свойство с путем к классу в свойстве dql ORM.

# app/config/config.yml
# Doctrine Configuration
doctrine:
# Search for the ORM property
orm:
# Those values should be already in your file and this doesn't matter
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# We need this the dql property to register the custom doctrine functions :
dql:
string_functions:
# Match agains should have the path to the SOUNDEX class created in the previous step
SOUNDEX: myBundle\Extensions\Doctrine\SoundexFunction

И ты готов к работе! очистить кеш в случае, если вы работаете в среде Prod и давайте создадим несколько запросов.

использование

Предложение SOUNDEX доступно для его использования, вы можете использовать его в построителе запросов или в простом DQL.

getDoctrine()->getManager();
$repository = $em->getRepository('myBundle:Entity');
$results = $repository->createQueryBuilder('a')
->where("SOUNDEX(a.table_field) LIKE SOUNDEX(:search)")
// To use SOUNDEX with another methods like MATCH_AGAINST
// You can use the orWhere('SOUN....') clause instead of where
// In case that you don't want to use parameter, you can set directly the string into the query
//->where("SOUNDEX(a.table_field) LIKE SOUNDEX('%Title to search mispillid%')")
->setParameter('search','%Title to search mispillid%')
->getQuery()
->getResult();
dump($results);
}
}

Обратите внимание, что мы используем %text% чтобы сопоставить все записи, которые содержат этот текст. Вам не нужно использовать подстановочные знаки, если хотите.

Понимание того, как работает soundex

Учитывая следующую таблицу (с сущностью Breed) в базе данных:

Я БЫ
НАЗВАНИЕ
1Affenpinscher
2Аляскинский маламут
3Эрдельтерьер
4Акита
5Австралийская овчарка

Пользователь может неправильно ввести породу собаки, однако совпадение будет возвращено, т.е.

Пользовательский ввод
Ожидаемый результат
afhenpinsher1 — Affenpinscher
алскан маламут2 — Аляскинский маламут
Эрдельтерьер3 — эрдельтерьер
aquita4 — Акита
австралийский чабан5 — Австралийская овчарка

Что делает soundex, так это просматривает фонетику конкретной строки и преобразует ее в стандартизированную строку (при использовании этого процесса буквы и слова, которые звучат одинаково, будут возвращать то же значение, например, буква ‘d’ будет иметь то же значение, что и буква «т»). Это не очень полезно, но на самом деле так, т.е. если вы выполняете следующий запрос:

select 'text', soundex('text');

В результате вы получите следующую таблицу:

текстSOUNDEX ( «текст»)
текстT230

И если вы выполните текст с ошибкой, т.е. tixt, то таблица будет:

текстSOUNDEX ( «текст»)
текстT230

Обе строки возвращают одинаковое значение T230. Soundex — это фонетический алгоритм для индексации имен по звуку, как произносится на английском языке, SOUNDEX Коды из разных строк можно сравнить, чтобы увидеть, насколько похожи эти звуки при разговоре. Первый символ кода — это первый символ выражения, преобразованный в верхний регистр. Со второго по четвертый символы кода являются числами, которые представляют буквы в выражении. Буквы A, E, I, O, U, H, W и Y игнорируются, если они не являются первой буквой строки. Все международные буквенные символы за пределами диапазона A-Z рассматриваются как гласные. Следовательно, две строки, которые звучат почти одинаково, должны иметь идентичные строки soundex. Например, слова «текст» и «текст» оба производят звуковое выражение «T230».

Повеселись !

Ссылка на основную публикацию
Adblock
detector