我正在尝试将基于关键字分析器的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])');
谢谢,
基隆
答案 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]')