数据库中基于文本的搜索的最佳实践

时间:2012-01-23 18:58:10

标签: c# database search lucene.net porter-stemmer

我有一个应用程序,我需要在各种基于文本的字段中搜索。该应用程序是使用NHibernate作为ORM开发的。

我想在搜索中实施Porter Stemming,以便即使关键字与相似的字匹配也能够返回相关结果,例如,当搜索关键字为{时,产品的描述包含memories {1}}。

有人可以建议这类搜索的最佳做法吗?想到的第一个想法是在数据库中存储同一字段的两个版本,例如:

memory

Description Description_Search 列将是网站管理员输入的文本,并且是前端可见的文本。

Description将包含相同的文本,但是通过Porter-Stemming算法传递。然后,搜索查询将基于Description_Search字段,而不是Description_Search

这有意义吗?是否浪费空间必须存储几乎相同文本的两个版本?

另外,Description会在这种情况下提供帮助吗?我也在考虑将Lucene.Net集成到基于全文的搜索中,但还没有详细研究过。

提前致谢!

1 个答案:

答案 0 :(得分:0)

没有必要为此使用两个字段,一个就足够了。一个字段有两个“值”,一个存储可以使用Document.Get(...)检索,一个索引用于搜索。在技​​术上也不需要存储值,常见的解决方案是存储用于在数据库中查找原始内容的id。这还可以让您查找更多信息,例如作者信息和文档位置。

Lucene.Net在这种情况下会有所帮助,但它要求您自己编写基础架构。您需要注意配置分析器(通常无需配置),并为您的内容编制索引。正如在评论中提到的,您可以使用SQL Server的全文搜索功能,但这本身有一些限制(可能不会影响您)。

我使用SQL Server的FTS遇到了一个大问题,但是在Lucene.Net中工作(这是不公平的,因为你可以在Lucene.Net中做几乎任何事情,因为你写的代码就是这样做的)是重音灵敏度。我无法使用瑞典语规则对其进行配置,其中åäö应被视为真实字符。启用重音敏感度可以做到这一点,但这也意味着变音符被解析为真实字符,这意味着ñn不同。 (想象一下,搜索“墨西哥胡椒”并没有获得“jalapeño”的匹配)。禁用重音敏感度基本上会删除所有变音符号,将åäö变为aao,并且单词会变得完全不同。

在Lucene.Net中编写内容(与SQL Server FTS相比)允许您提供结果突出显示(在文档中显示与查询匹配的短语),搜索类似文档,拼写检查,自定义结果提升,方面,以及其他可以增强用户搜索体验的内容。