Нечеткий поиск — очень важная особенность поисковых систем. Вы можете реализовать нечеткий текстовый поиск в базе данных 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
) в базе данных:
1 | Affenpinscher |
2 | Аляскинский маламут |
3 | Эрдельтерьер |
4 | Акита |
5 | Австралийская овчарка |
Пользователь может неправильно ввести породу собаки, однако совпадение будет возвращено, т.е.
afhenpinsher | 1 — Affenpinscher |
алскан маламут | 2 — Аляскинский маламут |
Эрдельтерьер | 3 — эрдельтерьер |
aquita | 4 — Акита |
австралийский чабан | 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».
Повеселись !