【问题标题】:Searching and ranking short phrases (e.g. movie titles)搜索和排名短语(例如电影标题)
【发布时间】:2009-11-18 16:57:49
【问题描述】:

我正在尝试改进我们的短语搜索功能(在我们的例子中是电影标题),目前正在研究 SQL Server 2008 全文搜索,它提供了一些我们想要的功能:

  • 词干提取(例如,“saw”也表示“see”、“seen”等)
  • 同义词(例如“6”与“VI”同义)

然而,排名算法似乎有问题,将FREETEXTTABLE 与搜索词一起使用并提取RANK 字段。例如,当用户输入“saw”时,如果没有目录,我们得到的结果是:

RANK | Title
---------------------------------------------------------------------
180  | The Exorcist: The version you've never seen
180  | Saw IV
180  | Saw V
180  | Anybody Here Seen Jeannie?
180  | Seeing Red

所有这些都具有相同的排名,尽管人们很清楚第二个和第三个条目比其他词干匹配更好。

类似地输入“moon”会得到以下结果:

RANK | Title
---------------------------------------------------------------------
144  | Pink Floyd - The Dark Side of the Moon
144  | Fly Me To The Moon 3D
144  | Twilight: New Moon
144  | Moon

虽然没有词干匹配,但人们会清楚“月亮”的最佳匹配是“月亮”,而不是仅包含它作为标题一部分的较长标题,但 FTS 对它们进行平等排名.

我猜这可能与 SQL Server 对结果进行排序的方式有关,它将词干词和同义词与原始术语同等权重,并考虑了用于排名的词密度,这对于长段落来说会很好文本,但并不真正适用于像这样的短语。所以我开始觉得 FTS 不适合这份工作,很遗憾。

我真的不想重新发明轮子,那么是否有任何现有的搜索解决方案可以用于标题并提供良好的排名以及词干/词库功能?如果它有一个拼写检查器来实现像谷歌这样的“你的意思是......”功能也很好,所以“saww”会被更正为“saw”,“mon”会被更正为“moon”,等等。

【问题讨论】:

    标签: sql-server-2008 full-text-search


    【解决方案1】:

    听起来 SQL FTS 的排名很接近,但并不完全符合您的要求,并且您已将“不完全”的情况缩小到三个:

    • 屈折形式与非屈折形式的排名相同
    • 单词的排名与其同义词相同
    • 完全匹配(或短标题)的排名与长标题中的单字匹配相同

    这三者的共同点是,一个非常简单的自动结果后处理器可以使用这些规则来打破排名相同的结果之间的联系:如果存在完全匹配,则将其排在非完全匹配之上,并将较短的标题排在较长的标题之前。您可能需要考虑保留 FTS,并简单地将一些代码(在存储过程中或在您的应用程序中)放在 FTS 之上,根据您提到的标准对绑定结果组进行排序。这可能比切换到 Lucene 或其他非 Microsoft 全文搜索实现更容易。

    如果我站在你的立场上,因为你已经有了一些可以使用 FTS 的东西,我会尝试上面的后处理技巧,看看它是否“足够好”来满足你的需求,因为它可能是最简单的事情。

    如果还不够好,我会先查看Lucene.NET(免费)、Solr(免费)和dtSearch($$$)。请注意,没有一个比 FTS 更简单——尤其是 Lucene.NET,它是 AFAIK 最流行的并且功能非常齐全,但需要大量的编码、配置、维护等。你可以看到 this SO thread对于其他一些意见,如果您想要更多意见,那么在 SO 和其他地方可能会有更多这样的线程。

    如果您正在寻找“您的意思是...”拼写建议功能。 Pro Full-Text Search in SQL Server 2008 中有一个在 FTS 之上构建此类功能的示例(链接包含谷歌图书的一些摘录)。这能满足您的需求吗?如果没有,lots of other options 既有免费的,也有免费的。

    【讨论】:

    • 我可以从经验中谈起在 dtSearch 中输入查询的便利性……它比 SQL Server 容易得多。不幸的是,将结果插入计算机程序并在服务器环境中设置它并不比 SQL 服务器容易......(当然我不是数据库专家,所以这可能表明我的想法存在偏见......)跨度>
    【解决方案2】:

    我知道你对重新发明轮子不感兴趣,但我想贡献一些至少可以让你的轮子转动的东西。

    'How to Strike a Match' 是我最喜欢的关于这个主题的帖子之一。在其中,作者根据单词之间连续双联的相似性来匹配字符串。

    例如,'search' 和 'smirch' 都按字母分成双联体:se、ea、ar、rc、ch 表示搜索,sm、mi、ir、rc、ch 表示 smirch。然后匹配双峰的数量乘以 2(rc 和 ch 匹配,所以 2 * 2)并除以双峰的总数(在这种情况下为 5 + 5 = 10)。 4/10 = 搜索和污点之间的匹配率为 40%。

    这会惩罚长的、不相关的字符串,因为它们会增加分母而不增加分子。

    在您的第二个示例中,该算法将突出月亮作为最佳示例,但不会保留月亮的暗面等 - 它们只会排名较低。在您的第一个示例中,您必须在调用此算法之前应用某种词汇转换,因为它无法找到词干变化的相似词(如 see / saw / seen),尽管它可以很好地处理非词干-转换器(法国/法语)。

    我还没有考虑如何在 SQL 应用程序中直接实现这一点。

    【讨论】:

      【解决方案3】:

      在生产环境中使用过 SQL Server (2005) FullText 和 Lucene(.NET),我真的认为 Lucene 是更好的选择:

      SQL Server FTS 既好又快;但是您不能真正操纵索引的生成方式。此外,您不能只“看到”索引表。所有实现都被隐藏起来,因此该工具非常适合开箱即用的通用 FTS,但对于特定应用程序来说更难。

      另一方面,Lucene 已在多种场景中使用和测试(如果您决定采用该方法,我强烈推荐 Lucene in Action)。即使现有的实现不能完全满足您的需求,您也可以随时创建一个“新的”特定实现(编写您自己的分析器/标记器/过滤器 - 词干分析器!! - 1),尽管 lucene 的参数化量很多(2)您可以随时使用Luke (3) 检查索引的内容。 您还将获得一个独立于数据存储的搜索应用程序 (4), 它同样适用于 Java && .NET (5)。此外,如果这让你打勾,还有 Hibernate && NHibernate 实现 (Hibernate Search - 6)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-15
        • 1970-01-01
        • 1970-01-01
        • 2019-09-11
        相关资源
        最近更新 更多