SQL全文索引器,完全匹配和转义

时间:2011-01-19 11:27:08

标签: sql-server indexing lucene.net sql-server-2008-r2 full-text-indexing

我正在尝试将基于关键字分析器的Lucene.NET索引替换为基于SQL Server 2008 R2的索引。

我有一个表,其中包含我需要查询的自定义索引字段。索引列的值(见下文)是来自一系列.NET类型的自定义索引字段的名称/值对的组合 - 实际值是在运行时从属性中提取的,因为结构是未知的。

我需要能够使用AND和OR搜索集合名称和值对,并返回查询匹配的行。

Id          Index
====================================================================
1           [Descriptor.Type]=[5][Descriptor.Url]=[/]
2           [Descriptor.Type]=[23][Descriptor.Url]=[/test]
3           [Descriptor.Type]=[25][Descriptor.Alternative]=[hello]
4           [Descriptor.Type]=[26][Descriptor.Alternative]=[hello][Descriptor.FriendlyName]=[this is a test]

一个简单的查询如下所示:

select * from Indices where contains ([Index], '[Descriptor.Url]=[/]');

该查询将导致以下错误:

Msg 7630, Level 15, State 2, Line 1
Syntax error near '[' in the full-text search condition '[Descriptor.Url]=[/]'.

因此,考虑到这一点,我将Index列中的数据更改为使用|而不是[]

select * from Indices where contains ([Index], '|Descriptor.Url|=|/|');

现在,虽然该查询现在有效,但是当我运行它时,将返回包含Descriptor.Url并以/开头的所有行,而不是完全匹配的记录(在这种情况下恰好是一个)。

我的问题是,如何将查询转义为[]的帐户,并确保只返回完全匹配行?

更复杂的查询看起来有点像这样:

select * from Indices where contains ([Index], '[Descriptor.Type]=[12] AND ([Descriptor.Url]=[/] OR [Descriptor.Url]=[/test])');

谢谢,
基隆

2 个答案:

答案 0 :(得分:1)

您的主要问题是使用SQL分词器和CONTAINS语法。默认情况下,SQL wordbreakers消除标点符号,并规范化数字,日期,网址,电子邮件地址等。它还会降低所有内容的含量,并且会产生词语。

所以,对于你的输入字符串:

  

[Descriptor.Type] = [5] [Descriptor.Url] = [/]

您可以将以下标记添加到索引(及其位置)

  

描述符类型nn5 5描述符url

(注意:nn5是一种简化以不同格式给出的查询数字和日期的方法,原始数字也在同一位置编入索引)

因此,正如您所看到的,标点符号甚至不存储在全文索引中,因此,无法使用CONTAINS语句查询它。

所以你的陈述:

select * from Indices where contains ([Index], '|Descriptor.Url|=|/|'); 

在将查询生成器提交到全文索引之前,查询生成器实际上将其归一化为“descriptor url”,因此对“url”旁边的“描述符”的所有条目进行命中,不包括标点符号。

您需要的是LIKE statement

答案 1 :(得分:0)

使用“|”因为您的分隔符导致包含查询想到OR。这就是为什么你会得到意想不到的结果。你应该能够像这样逃避括号:

SELECT * FROM Indices WHERE 
    contains ([Index], '[[]Descriptor.Type]=[[]12]')