我有一个Web应用程序,允许用户将Latex内容保存到SQL Server 2012数据库。我正在运行如下的全文查询来搜索Latex表达式。
SELECT MessageID, Message FROM Messages m WHERE CONTAINS (m.Message, N'2x-4=0');
我在上面的查询中遇到的问题是上面查询返回的一些消息不包含乳胶表达式2x-4=0
。例如,上述查询也返回保存值如下的消息。您可以清楚地看到此消息中没有包含2x-4 = 0.
<p>Another example of inline Latex is \$x=34\$.</p>
<p>What are the roots of following equation: \$x^2 - 2x + 1 = 0\$?</p>
问题
为什么会发生这种情况,是否有办法在进行全文搜索以查找乳胶表达式2x-4 = 0
时返回正确的记录?我试图重新填充正在使用的表的全文搜索数据,但它没有效果。
更新1
奇怪,但以下Latex表达式过滤器始终返回完全匹配的结果。我现在正在寻找$2x-4=0$
而不是2x-4=0
。
SELECT MessageID, Message FROM Messages m WHERE CONTAINS (m.Message, N'$2x-4=0$');
我的app中有两种类型的乳胶表达分隔符:$$
用于段落显示,\$
用于内联显示Latex表达式,因此乳胶表达式周围总会有一个$符号存储在数据库中,虽然尾随分隔符可能是\$
但是全文搜索似乎忽略了反斜杠字符。
为什么这个修改后的查询返回完全匹配,我不清楚。
更新2
另一种准确工作的方法如答案所述。对此的完整查询如下所述。因此,LIKE运算符最终只扫描通过全文搜索查询选择的那些行。
WITH x AS
(SELECT MessageID,
Message
FROM Messages m
WHERE CONTAINS (m.Message,
N'2x-4=0') )
SELECT MessageID,
Message
FROM x
WHERE x.Message LIKE "%2x-4=0%"
答案 0 :(得分:2)
要了解它为何会发生,您可以运行以下查询(1033
是英语语言ID):
select * from sys.dm_fts_parser('2x-4=0', 1033, 0,1)
在我的实例中,它会返回以下结果:
请注意,除2x
外,搜索条件的所有其他部分都被视为干扰词。因此,我怀疑您的全文索引根本没有完整的2x-4=0
字符串,而是会出现2x
出现的结果。
我尝试将2x-4=0
添加到我自己的FTS索引中,CONTAINS
能够将CONTAINS(col, '2x-4=0')
和CONTAINS(col, '"2x-4=0"')
作为最佳结果找到它。但是,在完全匹配后,包含了部分匹配。
请注意,当在搜索字词=
周围添加额外的空格时,FTS解析器不会接受它并抱怨语法错误。
答案 1 :(得分:1)
CONTAINS
更像是最终用户搜索操作,支持NEAR
,AND
和OR
等关键字。尝试在引号内添加引号,以强制使用完整的搜索字词:
SELECT MessageID, Message FROM Messages m WHERE CONTAINS (m.Message, N'"2x-4=0"');
这在documentation中称为<simple-term>
。
您还可以尝试LIKE
operator:
SELECT MessageID, Message FROM Messages m WHERE m.Message LIKE '%2x-4=0%';
但请注意,这可能比CONTAINS
慢,因为它不使用全文搜索索引。如果它太慢,也许您甚至可以在一个查询中将它们组合在一起,因此CONTAINS
用于使用索引将结果集过滤到非噪声词,然后LIKE
适用最后的匹配。