搜索和排名短语(例如电影片名)

时间:2009-11-18 16:57:49

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

我正在尝试提高短语的搜索功能(在我们的案例中是电影片名),目前正在查看SQL Server 2008全文搜索,它提供了我们想要的一些功能:

  • 词干(例如“锯”也意味着“看”,“看”等)
  • 同义词(例如“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不适合这项工作。

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

3 个答案:

答案 0 :(得分:7)

听起来像SQL FTS的排名很接近,但并不完全是,你正在寻找什么,而且你已经将“不完全”的情况缩小到三个:

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

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

如果我在你的鞋子里,因为你已经有了与FTS合作的东西,我会尝试上面的后处理黑客,看看它是否“足够好”以满足你的需求,因为它可能是最简单的事情。

如果不够好,我会先查看Lucene.NET(免费),Solr(免费)和dtSearch($$$)。请注意,没有一个像FTS一样简单 - 尤其是Lucene.NET,它是最受欢迎的AFAIK,功能非常全,但需要大量的编码,配置,维护等等。你可以看到{{3对于其他一些观点,如果你想要更多的意见,可以在SO和其他地方有更多这样的线程。

如果您正在寻找“你的意思是......”拼写建议功能。在this SO thread中有一个在FTS之上构建此类功能的示例(链接包含Google Books的一些摘录)。这会满足您的需求吗?如果没有,Pro Full-Text Search in SQL Server 2008都是免费的而不是。

答案 1 :(得分: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 =搜索和smirch之间40%的匹配。

这会惩罚长而无关的字符串,因为它们会在不增加分子的情况下增加分母。

在你的第二个例子中,这个算法会突出月亮作为最好的例子,但不会不能保留月亮的黑暗面等 - 他们只会排名更低。在你的第一个例子中,你必须在调用这个算法之前应用某种词法转换,因为它将无法找到类似词干变化(如see / saw / seen),尽管它可以很好地处理非词干 - 换包者(法国/法国)。

我还没想过如何在SQL应用程序中直接实现它。

答案 2 :(得分:0)

在生产环境中使用过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)。