【问题标题】:Handling simple grammar in a PHP search engine在 PHP 搜索引擎中处理简单语法
【发布时间】:2012-07-17 01:22:33
【问题描述】:

我正在使用 MySQL 和 PHP 为我的网站创建一个简单的搜索功能。现在,如果在搜索栏中输入单词“cat”,我将无法检索带有单词“cats”的文章,反之亦然。结尾的“ed”也是一样。

我能想到的解决这个问题的唯一方法是从每个长度超过一定长度的单词的末尾删除所有“s”和“ed”(以避免将“Ted”变成“T” , ETC)。然而,这个简单的解决方案远非完美。我希望有人可以为我提供更好的解决方案。

【问题讨论】:

  • -ed 并非总是如此。不规则的人(被抓、喂、跑等)呢?您不能总是通过简单的字符串操作将过去时转换为现在(或无限)。你需要一本字典。另外,您打算如何区分名词(搜索不应该计算 -ed 和应该计算的动词)?
  • @PhpMyCoder:我做不到,这正是我在 SO 上问这个问题的原因。否则我可以简单地删除所有“ed”,我的所有问题都会得到解决。

标签: php mysql search


【解决方案1】:

您所指的技术称为词干提取。由于对语言的影响很大,这在应用程序级别很难自己处理。如果您不想处理这个问题,您可以让 MySQL 为您完成繁重的工作,具体取决于您正在运行的 MySQL 版本。如果您使用的是 5.6.4 或更高版本,则它内置于 MyISAM 表和 InnoDB 表的全文搜索机制中。在 5.5 到 5.6.3 版本中,它是为 MyISAM 而不是 InnoDB 表内置的。对于 5.1 版,mnoGoSearch 提供了一个插件。在 5.1 之前,我认为您需要在应用程序级别处理它,但我尚未确认。

这些链接可能会帮助您入门。

请注意停用词列表,这是一个非常常见且通常很短的单词列表,在处理查询时会在搜索文本中被忽略。如果停用词列表阻止您获得预期结果,则有一些设置可以控制停用词列表。您可能希望将最小字长设置为 2 或 3(默认为 4)并删除默认列表中的许多字。

如果您确实想自己或使用 PHP 处理词干提取,可以使用 a detailed technical discussion of the Porter Stemming Algorithm by Martin Porter,并且至少有两个 PHP 实现可用,an older one in PHP4 by Jon Abernathy 可能存在一些缺陷,a newer one in PHP5 by Richard Heyes

我假设您主要关注英语,但我相信其他语言也有一些支持。

作为mentioned by rnmccall,如果您需要更高级的搜索功能,您可能需要使用 Sphinx 或 Apache Lucene。

【讨论】:

    【解决方案2】:

    问题中描述的删除后缀的策略通常称为词干提取。如果您仍然对采用该策略感兴趣,您应该查看http://tartarus.org/~martin/PorterStemmer/ 了解词干提取的背景。该页面还包含 Porter 词干分析器的 PHP 实现和更现代算法的链接。

    Sphinx 使用了这种词干搜索方法,pydoc 也使用了这种方法。

    词干提取方法的主要好处是它简单明了并且可以轻量级。

    但是,如果您想要更复杂的搜索功能,您可能应该使用Apache Lucene 之类的东西。

    【讨论】:

      【解决方案3】:

      我建议使用 Lucene。由于您没有运行复杂的查询 - 只是查找索引,因此它还会减少您的数据库的压力。您还可以使用 Lucene 运行模糊搜索。

      【讨论】:

        【解决方案4】:

        你可以简单地使用

        SELECT * FROM topics WHERE Title LIKE '%cat%'
        

        在查询中搜索标题为猫和猫的主题。如果要从大文本内容中搜索数据,可以使用 FullTextSearch。在这种情况下,您只能使用 MyISAM 表。你可以阅读全文搜索文档here

        【讨论】:

          【解决方案5】:

          没有ed 或任何你想删除的东西。因为您正在从段落中搜索字符串,所以您需要提供特定的关键字来搜索。该关键字可以是完整的字符串(单词),也可以是子字符串(单词的一部分)。

          例子:-

          您在black 漏洞中。

          现在您想通过提供bla 作为搜索字符串来搜索black。然后查询如下:-

          SELECT * FROM TABLE_NAME WHERE YOUR_FIELD_NAME LIKE '%BLA%'
          

          使用上面的查询与您的内容完全匹配。您可以提供您想要搜索的段落/段落中的任何子字符串。

          希望对你有帮助。

          【讨论】:

            【解决方案6】:

            可能的解决方案:

            1.最简单的实现 -> 使用 %operator

            喜欢 %cats%

            2.使用 solr 快速实现,因为那里实现了最优算法。

            注意:你也可以在缓存中缓存你的结果

            【讨论】:

              【解决方案7】:

              一个简单的查询是:

                  select * from table where item like '%name%'
              

              要避免 t 和 ted 的事情,请使用 substr() 函数并将字符串设置为通用大小,然后将该字符串放入 where 子句中。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-04-04
                • 1970-01-01
                • 1970-01-01
                • 2013-07-14
                • 2014-08-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多