注意:我我使用SQL的全文搜索功能,CONTAINS子句和所有 - *是全文的通配符,%仅用于LIKE子句
我现在在几个地方读过MS SQL不支持“前导通配符”搜索(例如使用“* overflow”来匹配“stackoverflow”)。我正在考虑使用CLR function to add regex matching,但我很想知道人们可能会有哪些解决方案。
更多信息:You can add the asterisk only at the end of the word or phrase. - 以及我的实验经验:匹配“myvalue”时,“my *”有效,但“(星号)值”返回时不匹配一个简单的查询:
SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');
因此,我需要一种解决方法。我只在实际搜索页面上使用我的网站搜索 - 所以它的工作方式基本上与Google的工作方式相同(在Joe Sixpack类型的用户眼中)。不是那么复杂,但这种匹配真的不应该失败。
答案 0 :(得分:22)
仅针对前导通配符的解决方法:
使用*
查找反转文本SELECT *
FROM TABLENAME
WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');
当然有许多缺点,只是为了快速解决方法......
更不用说CONTAINSTABLE ......
答案 1 :(得分:14)
领先通配符的问题:它们无法编入索引,因此您正在进行全表扫描。
答案 2 :(得分:6)
可以在单词或短语的末尾使用通配符“*”(前缀搜索)。
例如,此查询将找到所有“datab”,“database”,“databases”......
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')
但是,不可思议的是,无法使用前导通配符进行搜索。
例如,此查询将找不到“数据库”
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')
答案 3 :(得分:4)
或许为这个帖子添加清晰度,从我在2008 R2的测试中,Franjo在上面是正确的。在处理全文搜索时,至少在使用CONTAINS短语时,您不能在功能上使用前导,只能使用尾随。 *是通配符,而不是全文%。
有人建议忽略*。情况似乎并非如此,我的结果似乎表明尾随*功能确实有效。我认为领先*会被引擎忽略。
我添加的问题是,使用带有通配符的全文的同一查询在2005年(20秒)使用通配符的速度相对较快,并且在将数据库迁移到2008 R2后减慢到12分钟。似乎至少有一个其他用户有类似的结果,他开始了一个论坛帖子,我加入了...... FREETEXT仍然工作得很快,但“看起来”似乎已经改变了2008年处理尾随*在CONTAINS中的方式。他们在升级顾问中提供各种警告,他们“改进”了全文,因此您的代码可能会中断,但不幸的是,他们没有给您任何关于某些弃用代码等的特定警告......只是他们改变了它的免责声明,使用风险自负。
http://social.msdn.microsoft.com/Forums/ar-SA/sqlsearch/thread/7e45b7e4-2061-4c89-af68-febd668f346c
也许,这是与这些问题相关的最接近的MS点击... http://msdn.microsoft.com/en-us/library/ms143709.aspx
答案 4 :(得分:3)
值得记住的一点是,与其他通配符使用相比,领先的通配符查询具有显着的性能溢价。
答案 5 :(得分:2)
SQL Server中的通配符是%
符号,它可以很好地工作,领先,尾随或其他方式。
那就是说,如果您要进行任何严肃的全文搜索,那么我会考虑使用全文索引功能。使用%
和_
通配符会导致数据库严重受损。
答案 6 :(得分:1)
从SQL Server联机丛书:
写入全文查询 您必须使用Microsoft SQL Server 2005 学习如何使用CONTAINS和 FREETEXT Transact-SQL谓词和 CONTAINSTABLE和FREETEXTTABLE 行集值函数。
这意味着上面用%和_写的所有查询都不是有效的全文查询。
以下是调用CONTAINSTABLE函数时查询的示例。
SELECT RANK,* FROM TableName, CONTAINSTABLE(TableName,*,' “* WildCard”')searchTable WHERE [KEY] = TableName.pk ORDER BY searchTable.RANK DESC
为了让CONTAINSTABLE函数知道我正在使用通配符搜索,我必须用双引号将其包装起来。我可以在开头或结尾使用通配符*。当您为CONTAINSTABLE函数构建搜索字符串时,还可以执行许多其他操作。你可以搜索另一个单词附近的单词,搜索屈折单词(drive = drives,drive,driving和driven),并搜索另一个单词的同义词(metal可以有同义词,如铝和钢)。
我刚刚创建了一个表,在表上放了一个全文索引并进行了几次测试搜索并且没有问题,因此通配符搜索按预期工作。
[更新]
我看到你已经更新了你的问题并且知道你需要使用其中一个功能。
您仍然可以在开头使用通配符进行搜索,但如果该单词不是通配符后面的完整单词,则必须在末尾添加另一个通配符。
Example: "*ildcar" will look for a single word as long as it ends with "ildcar".
Example: "*ildcar*" will look for a single word with "ildcar" in the middle, which means it will match "wildcard". [Just noticed that Markdown removed the wildcard characters from the beginning and ending of my quoted string here.]
[更新#2]
Dave Ward - 使用带有其中一个函数的通配符不应该是一个巨大的性能。如果我创建一个只有“*”的搜索字符串,它将不会返回所有行,在我的测试用例中,它返回了0条记录。
答案 7 :(得分:1)
仅供参考,Google不进行任何子字符串搜索或截断,向右或向左。他们有一个通配符*来查找短语中的未知单词,但不是单词。
Google与大多数全文搜索引擎一起,根据字母的字母顺序设置倒排索引,并提供指向源文档的链接。即使对于巨大的索引,二进制搜索也很快。但是在这种情况下进行左截断真的很难,因为它失去了索引的优势。
答案 8 :(得分:1)
作为存储过程中的参数,您可以将其用作:
useAsDefault
答案 9 :(得分:0)
说到全文搜索,我的钱没有什么比Lucene好。有一个.Net port available与使用Java版本创建的索引兼容。
您需要创建/维护索引,但是搜索速度非常快,您可以创建各种有趣的查询。即使索引速度也非常好 - 我们只需每天完成一次索引重建,不用担心更新它们。
例如,this search functionality由Lucene.Net提供支持。
答案 10 :(得分:0)
也许以下链接将为使用通配符提供最终答案:Performing FTS Wildcard Searches。
请注意以下段落:"但是,如果指定“ Chain”或“Ch ain”,则无法获得预期结果。星号将被视为正常的标点符号,而不是通配符。 "
答案 11 :(得分:0)
答案 12 :(得分:-1)
%匹配任意数量的字符 _匹配单个字符
我从未使用过全文索引,但只需使用T-SQL字符串函数中的构建就可以完成相当复杂和快速的搜索查询。