本文概述
模糊搜索是Web搜索引擎的一个非常重要的功能。你可以通过结合使用内置用户功能(例如匹配匹配等)在MySQL数据库中实现模糊文本搜索。
为了即使输入拼写错误也能匹配结果, 我们也可以使用SOUNDEX本机MySQL函数来捕获它们。在本文中, 你将学习如何在Symfony项目中实现Soundex在理论上的用法。
注意:本教程适用于Symfony 2.x和Symfony3.x。
实现
首先, 请在捆绑包的根文件夹中找到自己, 并创建一个名为Extensions的文件夹(或根目录/ src), 然后在名为Doctrine的内部创建一个文件夹。在doctrine文件夹中创建一个名为SoundexFunction.php的新类, 并将以下代码保存在其中。
不要忘记根据项目中的位置更改名称空间。
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace ourcodeworld\Extensions\Doctrine;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
/**
* SoundexFunction ::= "SOUNDEX" "(" StringPrimary ")"
*/
class SoundexFunction extends FunctionNode
{
public $stringExpression = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->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属性和类路径保存在ORM的dql属性中即可。
# 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
你已经准备好出发了!如果你在产品环境中工作, 请清除缓存, 让我们创建一些查询。
用法
SOUNDEX子句可供使用, 你可以在查询生成器或纯DQL中使用它。
<?php
class LandingController extends Controller
{
public function indexAction(Request $request)
{
$em = $this->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):
ID | 名称 |
---|---|
1 | 阿芬平彻 |
2 | 阿拉斯加雪橇犬 |
3 | 大狗梗 |
4 | 秋田 |
5 | 澳大利亚牧羊犬 |
用户可以输入错误的犬种, 但是将返回匹配项, 即:
用户输入 | 预期结果 |
---|---|
阿芬平 | 1-阿芬平彻 |
阿拉斯加雪橇犬 | 2-阿拉斯加雪橇犬 |
Airdale梗 | 3-大狗梗 |
阿基塔 | 4-秋田 |
澳大利亚牧羊犬 | 5-澳大利亚牧羊犬 |
soundex的作用是查看特定字符串的语音并将其转换为标准字符串(使用此过程, 听起来相似的字母和单词将返回相同的值, 例如, 字母” d”将具有与字母” t”)。听起来根本没有什么帮助, 但实际上是, 即执行以下查询:
select 'text', soundex('text');
结果将得到下表:
文本 | SOUNDEX(“文字”) |
文本 | T230 |
而且, 如果你执行拼写错误的文本(即tixt), 则该表将为:
文本 | SOUNDEX(“文字”) |
文本 | T230 |
两个字符串返回相同的T230值。 Soundex是一种语音算法, 用于按声音索引名称(英语发音), 可以将来自不同字符串的SOUNDEX代码进行比较, 以查看说话时字符串听起来的相似程度。代码的第一个字符是表达式的第一个字符, 转换为大写。该代码的第二个到第四个字符是代表表达式中字母的数字。字母A, E, I, O, U, H, W和Y会被忽略, 除非它们是字符串的第一个字母。所有A-Z范围以外的国际字母字符都被视为元音。因此, 听起来几乎相同的两个弦应该具有相同的soundex弦。例如, 单词” text”和” tixt”都产生” T230″的声音。
玩得开心 !
评论前必须登录!
注册