【问题标题】:How to omit "THE" in search using PHP and MYSQL如何使用 PHP 和 MYSQL 在搜索中省略“THE”
【发布时间】:2011-01-25 18:24:48
【问题描述】:

我正在为一个项目执行“字母顺序搜索”模块。

那就是它看起来像

A B C D E F . . . . . . . . . ... . . . . . ... . . Z

当我点击“A”时,结果应该按“A”排序。这对所有字母来说都是一样的。

现在我的问题如下:

  • 比如有一部电影叫《木乃伊》。

  • 我所做的是当点击“ALPHABET T”时,相应的电影将被排序。

  • 但我的客户要求是“木乃伊”电影必须在用户点击“M”而不是“T”时进行排序

  • 因为“a, an, the”是“ARTICLES”,没有任何意义。

我希望现在每个人都能理解我的问题是什么......

任何帮助将不胜感激。

提前致谢

【问题讨论】:

    标签: php mysql sorting stop-words


    【解决方案1】:

    假设您不希望修改表的内容(因此查询效率略低),下面的方法应该可以解决问题。
    (如果您确实有闲暇修改表格,请参阅本答案末尾的建议)

    SELECT Title
    FROM myTable
    WHERE (Title LIKE 'x%' OR Title LIKE 'THE x%')
      -- AND Title NOT LIKE 'THE [^T]%'   
    ORDER BY Title
    

    注意事项:
    -x 指定所需的字母(例如:LIKE 'A%' 等)
    - 仅当“X”是字母“T”时才需要“AND TITLE NOT LIKE”额外条件(否则在功能上是多余的,但不会改变结果)
    - 我不确定[^xyz] 是否支持(即NOT 字符x、y 或z),所以[^T] 可以用它的正等价物代替,比如[A-RS-Z0-9]

    还有一些其他停用词需要考虑(“A”、“AN”、“OF”...),但对于书籍或电影标题,通常只考虑“THE”。如果一定要处理其他文章,逻辑可以扩展为:

    SELECT Title
    FROM myTable
    WHERE (Title LIKE 'x%' 
        OR Title LIKE 'THE x%' 
        OR Title LIKE 'A x%' 
        OR Title LIKE 'AN x%') 
     -- the following is only needed when "x" is either the letter T or A.
     -- AND (Title NOT LIKE 'THE [^T]%' 
     --      AND Title NOT LIKE 'A [^A]%' 
     --      AND Title NOT LIKE 'AN [^A]%'
     --  )
    ORDER BY Title
    



    有更好的解决方案,如果您可以修改表格的内容。其中一些意味着预先计算一个或几个额外的列(并在添加新记录时维护它/这些)。

    • 例如 Cletus 在这篇文章中对“sort_column”方法的回答,其中额外的列包含去除了任何不受欢迎的前导干扰词的标题。除了作为 OP 首字母搜索问题中的过滤字段之外,该列还可以用于以更友好/明智的方式对由与首字母无关的过滤器生成的标题列表进行排序和/或标题的开头(比如按年份搜索)。
    • 上述方法的一种变体是只存储“有效”的首字母(除去不想要的噪音的那个),这样可以使列更小,但用途也更少。
    • 可以更新标题列本身,存储标题的修改形式,从而将无关的前导干扰词移动到括号之间的字符串末尾。这种做法在书目类型目录中很常见。

    【讨论】:

    • 嗨.. 非常感谢您的努力。我得到了“喜欢”的结果 AN 没有得到“不喜欢”的结果......要进行任何更改.. 我对“T”的查询是 Select * from movies Where film_status='Active' AND ( user_id='3' OR distribution='3') AND (film_name LIKE 'T%' OR film_name LIKE 'THE T%' OR film_name LIKE 'AT%' OR film_name LIKE 'AN T%' OR film_name LIKE 'The T% ' OR film_name LIKE 'An T%') AND (film_name NOT LIKE 'THE [^T]%' AND film_name NOT LIKE 'The [^T]%' AND film_name NOT LIKE 'A [^T]%' AND film_name NOT LIKE 'AN [^T]%' ) 按电影名称排序
    • @Fero:是的,您评论中的查询看起来正确。请注意,有一些方法可以使 mySQL 以不区分大小写的方式处理文本。这应该可以让您免于使用“The”之类的所有这些额外条件。
    【解决方案2】:

    基本上你是如何做到这一点的,你有一个额外的列用于排序。如果您有一个带有name 列的movie 表,请添加另一个名为sort_name 的列。这应该包含小写的电影标题,并从前面删除您想要忽略的任何单词(例如“the”、“a”)。

    不要尝试动态执行此操作。

    当字段更新时,您还必须更新 sort_name 列。您可以随时重建它,当然您必须对其进行索引。然后就做:

    SELECT *
    FROM movies
    WHERE sort_name LIKE 'a%'
    

    【讨论】:

      【解决方案3】:

      您在这里真正要问的是如何删除“停用词”(“the”只是一个示例;您需要删除“of”、“a”等)。尝试对停用词集进行硬编码是一件非常痛苦的事情,而且随着语料库的变化,您将不得不更改代码。

      相反,您应该尝试使用一种算法,该算法将根据您的语料库推断停用词的含义。做这种事情的算法是众所周知的,并被搜索引擎采用。一个很好用的叫做TF/IDF

      【讨论】:

      • +1 用于提及“停用词”这一短语,因为这是解决此问题的关键(并拥有卓有成效的 SO/google fu)
      • +1 这回答了我关于“德语/法语/等文章怎么样?”的问题
      猜你喜欢
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多