【问题标题】:SQL Full Text Indexer, exact matches and escapingSQL全文索引器,完全匹配和转义
【发布时间】:2011-06-11 16:52:59
【问题描述】:

我正在尝试将基于关键字分析器的 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 并以 / 开头的行,而不是完全匹配的记录(在这种情况下正好是一条)。

我的问题是,我怎样才能逃避查询以解释 [] 并确保只返回 exact 匹配行?

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

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

谢谢,
基隆

【问题讨论】:

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


    【解决方案1】:

    您的主要问题在于使用 SQL 分词器和 CONTAINS 语法。默认情况下,SQL 分词器会消除标点符号,并将数字、日期、网址、电子邮件地址等标准化。它还将所有内容都小写,并为单词添加词干。

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

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

    您将在索引中添加以下标记(连同它们的位置)

    描述符类型 nn5 5 描述符 url

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

    因此,如您所见,标点符号甚至没有存储在全文索引中,因此无法使用 CONTAINS 语句对其进行查询。

    所以你的陈述:

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

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

    您需要的是LIKE statement

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我已经尝试过了,但我最担心的是返回的结果不正确。谢谢。
      • select * from Indices where contains ([Index], '[[]Descriptor.Url]=[[]/]'); 给你什么错误?这应该允许您的查询在使用管道修改数据之前正确运行。将数据更改为管道后,您现在必须转义 |。查询应该类似于:select * from Indices where contains ([Index], 'Descriptor.Url\|=\|/\| ESCAPE '\'); - 不确定转义是否适用于包含,我目前没有要测试的数据库
      • 问题不在于转义,如果需要我可以更改分隔符,主要问题是返回的结果与预期不符。
      • 那么,使用方括号[] 和上面的转义序列,你仍然得到不正确的结果吗?如果您使用管道,它们是否会产生相同的错误结果?还是另外一套?根据您的描述,您似乎无法克服括号查询中的错误。
      • 我是,考虑到转义,两种方式都得到相同的错误结果。
      猜你喜欢
      • 2019-09-22
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      • 2011-12-19
      相关资源
      最近更新 更多