4

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

那就是它看起来像

ABCDEF 。. . . . . . . . ... . . . . . ... . . Z

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

现在我的问题如下:

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

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

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

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

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

任何帮助将不胜感激。

提前致谢

4

3 回答 3

2

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

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”额外条件(否则在功能上是多余的,但不会改变结果)
- 我不确定是否支持 the [^xyz](即不是字符 x、y 或 z),因此[^T]可以将其替换为正等价的 say [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 首字母搜索问题中的过滤字段之外,该列还可用于以更友好/明智的方式对由与首字母无关的过滤器生成的标题列表进行排序和/或标题的开头(比如按年份搜索)。
  • 上面的一个变体是只存储“有效”的首字母(过去的不想要的噪音),使列更小,但用途也更少。
  • 可以更新标题列本身,存储标题的修改形式,从而将无关的前导干扰词移动到括号之间的字符串末尾。这种做法在书目类型目录中很常见。
于 2010-03-10T05:53:08.017 回答
2

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

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

于 2010-03-10T05:58:38.927 回答
2

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

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

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

SELECT *
FROM movies
WHERE sort_name LIKE 'a%'
于 2010-03-10T06:22:42.560 回答