如何对SQLite查询进行排序而忽略文章(“the”,“a”等)?

时间:2010-09-12 18:33:12

标签: c# sqlite stop-words

我正在使用C#显示我从SQLite数据库调用的电影标题列表。目前,我正在使用一个自定义ListBox类,它具有从每个项目的开头剥离单词“The”的文本排序功能。但是,它似乎并不是最简单的方法,因为它从SQLite数据库调用,然后排序。我希望将其简化为一步,希望在我的“SELECT”查询中直接从数据库中进行排序。

我已经对此进行了一些搜索,并找到了一些建议,包括在数据库中创建一个额外的排序列。虽然这肯定是可能的,但我想知道是否有任何更简单的选项不需要插入几乎相同的重复信息(特别是如果数据库变大)。我是SQLite的新手,但我已经阅读了一些关于创建可用于创建自定义排序的collat​​e函数的内容。但是,我不确定这是否适合使用,似乎无法在C#中实现它。

希望有人能够分享一些指导。如果额外的排序列是最好的方法,那就是我要做的。

6 个答案:

答案 0 :(得分:6)

为避免插入重复数据,有两列:TITLE_PREFIX(通常为空,但有时包含“The”或“A”;此列上没有索引)和TITLE(包含没有“The”或“ “;这是您创建索引的列。”要显示数据,您必须组合TITLE_PREFIX和TITLE。但你只需搜索TITLE。

答案 1 :(得分:4)

以下是解决方案:

ORDER BY (CASE 
    WHEN sortTitle LIKE 'the %' THEN substr(sortTitle,5) 
    WHEN sortTitle LIKE 'a %' THEN substr(sortTitle,3) 
    WHEN sortTitle LIKE 'an %' THEN substr(sortTitle,4) 
    ELSE sortTitle END)

答案 2 :(得分:1)

您可以将每个标题分为两部分:titleprefix

使用SQLite,您可以通过|| operator组合2个字符串值,也称为concatenate operator

以下是一个例子:

SELECT prefix || ' ' || title FROM movies ORDER BY title

如果前缀为空,您也可以使用ltrim,因此前面没有空格:

SELECT ltrim(prefix || ' ' || title) FROM movies ORDER BY title

另一种方法是将前缀存储在标题的末尾。例如,在很多电影商店,你会看到类似的东西:

  

三个火枪手,

答案 3 :(得分:0)

在C#代码

如果您想在C#中执行此操作,请使用LINQ为您执行排序。我发布了一个full sample on PasteBin。这将允许您:

  • 避免重复数据库中的数据
  • 像往常一样利用数据库索引,无论哪个RDBMS
  • 在配置文件中输入干扰词,从而减少修改列表时的停机时间/重建/重新部署
  • 确保解决方案在客户端代码中更具可读性
DropDownList1.DataSource = myBooks.OrderBy(n => ReplaceNoise(n.Title))

public string ReplaceNoise(string input)
{
     string[] noise = new string[] { "the", "an", "a" };

     //surely this could be LINQ'd 
     foreach (string n in noise)
     {
         if (input.ToLower().StartsWith(n))
         {
             return input.Substring(n.Length).Trim();
         }
     }
     return input;
}

在您的SQLite声明中

如何简单地用空格中的空白替换噪音词呢?这是一个丑陋的第一步,但强烈考虑使用新列来存储此值以进行排序。

ORDER BY REPLACE(REPLACE([title],'the',''), 'a', '')

不可否认,当你最终得到这个时,这会变得很难看:

REPLACE(REPLACE(REPLACE(REPLACE([title],'The ',''),'a',''),'of',''),'by','')

答案 4 :(得分:0)

您可以尝试在标题上构建支持全文搜索(使用FTS模块)的表格。然后,您就可以对标题中的任何单词进行快速搜索,而无需您进行大量额外的工作。例如,用户查询 good bad ugly 可能会产生“好,坏,丑”作为其首批结果之一。所有这些的额外成本大约是文本本身长度的四分之一,但对于您的数据集可能更多,因为标题不是完整的英文文本。您还需要花时间构建这些额外的索引 - 您不希望在实时系统上的主数据集上构建它们(显然) - 但这不应该是一个太大的问题。

答案 5 :(得分:0)

创建一个虚拟列(可以在C#中实现的函数的结果)并对此虚拟列进行排序。无论你想要它做什么,该功能都可以像“三个火枪手”一样将“The”移动到最后,或者丢弃“The”。