php(模糊)搜索匹配
Posted
技术标签:
【中文标题】php(模糊)搜索匹配【英文标题】:php (fuzzy) search matching 【发布时间】:2011-03-13 15:09:57 【问题描述】:如果有人曾经向 digg 提交过故事,它会检查该故事是否已经提交,我假设是通过模糊搜索。
我想实现类似的东西,想知道他们是否使用了开源的 php 类?
Soundex 没有这样做,句子/字符串的长度可以达到 250 个字符
【问题讨论】:
您确定它们不只是匹配标题或网址吗?...我在 Levenshtein 公式上取得了巨大成功,但我确信它会开始在大型数据集上失败。 我现在正在尝试,但我认为它会融化一个具有任何吸引力的廉价托管帐户 【参考方案1】:您可以(取决于数据集的大小)使用 mysql 的 FULLTEXT 搜索,并查找在特定时间范围内得分高的项目,并向用户推荐这个/这些。
更多关于分数的信息:MySQL Fulltext Search Score Explained
【讨论】:
不幸的是,编程与数学息息相关。【参考方案2】:不幸的是,在 PHP 中执行此操作非常昂贵(CPU 和内存利用率很高)。但是,您当然可以将该算法应用于小型数据集。
具体扩展如何创建服务器崩溃:几个内置的 PHP 函数将确定字符串之间的“距离”:levenshtein 和 similar_text。 p>
虚拟数据:(假装是新闻头条)
$titles = $titles = explode("\n", $titles );
此时,$titles 应该只是一个字符串数组。现在,创建一个矩阵并将每个标题与每个其他标题进行比较,以了解相似性。换句话说,对于 5 个标题,您将获得一个 5 x 5 矩阵(25 个条目)。这就是 CPU 和内存接收器所在的位置。
这就是为什么这种方法(通过 PHP)不能应用于数千个条目的原因。但如果你想:
$matches = array(); foreach( $titles 作为 $title ) $matches[$title] = array(); foreach( $titles as $compare_to ) $matches[$title][$compare_to] = levenshtein($compare_to, $title); asort($matches[$title], SORT_NUMERIC);
此时,您基本上拥有的是一个带有“文本距离”的矩阵。在概念上(不是在实际数据中),它看起来有点像下表。请注意如何有一组 0 值沿对角线排列 - 这意味着在匹配循环中,两个相同的单词是 -- 嗯,相同的。
苹果 苹果 橙子 橙子 香蕉 苹果 0 1 5 6 6 苹果 1 0 6 5 6 橙色 5 6 0 1 5 橙子 6 5 1 0 5 香蕉 6 6 5 5 0实际的 $matches 数组看起来像这样(截断):
数组 ( [苹果] => 数组 ( [苹果] => 0 [苹果] => 1 [橙色] => 5 [香蕉] => 6 [橙子] => 6 ) [苹果] => 数组 ( ...
无论如何,您可以(通过实验)确定一个好的数值距离截断值可能最匹配的值 - 然后应用它。否则,请阅读 sphinx-search 并使用它——因为它确实有 PHP 库。
Orange,你很高兴你问这个问题?
【讨论】:
很好的理论解释。您对此有所了解!【参考方案3】:我建议获取用户提交的 URL 并将它们存储在多个部分中;域名、路径和查询字符串。使用 PHP parse_url() 函数导出提交的 URL 的各个部分。
索引至少是域名和路径。然后,当新用户提交 URL 时,您在数据库中搜索与域和路径匹配的记录。由于列被索引,您将首先过滤掉不在同一域中的所有记录,然后搜索剩余的记录。根据您的数据集,这应该比简单地索引整个 URL 更快。确保您的 WHERE 子句以正确的顺序设置。
如果这不能满足您的需求,我建议您尝试 Sphinx。 Sphinx 是一个开源的 SQL 全文搜索引擎,比 MySQL 内置的全文搜索要快得多。它支持词干提取和其他一些不错的功能。
http://sphinxsearch.com/
您还可以获取用户提交的标题或文本内容,通过函数运行它以生成关键字,并在数据库中搜索具有这些或类似关键字的现有记录。
【讨论】:
以上是关于php(模糊)搜索匹配的主要内容,如果未能解决你的问题,请参考以下文章
项目实战:Qt文件改名工具 v1.2.0(支持递归检索,搜索:模糊匹配,前缀匹配,后缀匹配;重命名:模糊替换,前缀追加,后缀追加)
项目实战:Qt文件改名工具 v1.2.0(支持递归检索,搜索:模糊匹配,前缀匹配,后缀匹配;重命名:模糊替换,前缀追加,后缀追加)