【问题标题】:mySQL - matching latin (english) form input to utf8 (non-English) datamySQL - 将拉丁(英语)表单输入匹配到 utf8(非英语)数据
【发布时间】:2014-11-28 21:05:39
【问题描述】:

我在 mySQL 中维护一个音乐数据库,我如何返回存储在 e.g.当人们搜索“Tiesto”时出现“Tiësto”?

所有数据都存储在全文索引下,如果这有什么不同的话。

我已经在 PHP 中使用了 Levenshtein,在 SQL 中使用了 REGEXP - 不是为了解决这个问题,而是为了提高一般的可搜索性。

PHP:

function Levenshtein($word) {

$words = array();
for ($i = 0; $i < strlen($word); $i++) {
    $words[] = substr($word, 0, $i) . '_' . substr($word, $i);
    $words[] = substr($word, 0, $i) . substr($word, $i + 1);
    $words[] = substr($word, 0, $i) . '_' . substr($word, $i + 1);
    }
$words[] = $word . '_';
return $words;
}

$fuzzyartist = Levenshtein($_POST['searchartist']);
$searchimplode = "'".implode("', '", $fuzzyartist)."'";

mySQL:

SELECT *
FROM new_track_database
WHERE artist REGEXP concat_ws('|', $searchimplode);

补充一点,我经常在 PHP 中执行字符集转换和字符串清理,但这些一直是另一种方式 - 标准化非拉丁字符。我无法理解执行相反的过程,但仅在某些情况下基于我存储的数据。

【问题讨论】:

  • 我已经在查询中使用了正则表达式;而且我还不够熟练,不知道如何组合多个正则表达式,如果这确实可能的话。因此,也许这个讨论仍然可以得到一些有用的东西。
  • 将数据存储在 MySQL 中,既可以作为原始版本,也可以作为仅包含拉丁字符的净化、可搜索版本?
  • 这是个好主意,wavemode。仅为全文搜索目的创建重复表并不麻烦。谢谢。
  • 您是否尝试过设置 utf8_unicode_ci 的集合,然后在运行常规查询期间?

标签: php mysql regex search levenshtein-distance


【解决方案1】:

一个可能的解决方案是在“艺术家”旁边的数据库中创建另一个列,例如“艺术家标准化”。在这里,在填充表格时,您可以插入字符串的“规范化”版本。然后可以针对 Artist_normalized 列执行搜索。

测试代码:

<?php
$transliterator = Transliterator::createFromRules(':: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD);
$test = ['abcd', 'èe', '€', 'àòùìéëü', 'àòùìéëü', 'tiësto'];
foreach($test as $e) {
    $normalized = $transliterator->transliterate($e);
    echo $e. ' --> '.$normalized."\n";
}
?>

结果:

abcd --> abcd
èe --> ee
€ --> €
àòùìéëü --> aouieeu
àòùìéëü --> aouieeu
tiësto --> tiesto

这个魔法是由 Transliterator 类完成的。指定的规则执行三个操作:分解字符串,删除变音符号,然后重新组合字符串,规范化。 PHP 中的 Transliterator 是在 ICU 之上构建的,因此通过这样做,您将依赖 ICU 库的表,这些表是完整且可靠的。

注意:此解决方案需要带有 intl 扩展名的 PHP 5.4 或更高版本。

【讨论】:

  • 遗憾的是我没有 5.4,但这仍然是一个巧妙的解决方案!并强化了上面的想法。模糊搜索就像一个黑洞;考虑到这确实是谷歌商业模式的基础,这并不奇怪。感谢您的时间和精力。
  • 如果您没有 5.4 或更高版本,请更改主机;)现在是 2014 年! @user3174541
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 2019-02-23
  • 2016-05-26
  • 2011-05-05
  • 2014-11-24
相关资源
最近更新 更多