MarkLogic中cts:search whitespace敏感/非敏感查询结果异常原因咨询
问题描述
我们有两个包含如下元素的XML文档:
<!-- Document 1 --> <LegacyCode>09Y14K012D3001</LegacyCode> <!-- Document 2 --> <LegacyCode>09 14 012 3001</LegacyCode>
我们使用以下cts:search查询尝试获取这些文档:
cts:search( doc(), cts:and-query(( cts:collection-query("XYZ"), cts:word-query("*09*14*012*3001*", ("punctuation-insensitive", "whitespace-insensitive", "wildcarded")) )) )
但该查询未返回预期文档。奇怪的是,若将选项改为"whitespace-sensitive",则能成功检索到目标文档。
已启用的索引设置
- word searches
- fast phrase searches
- fast case-sensitive searches
- fast diacritic-sensitive searches
- trailing wildcard searches
- trailing wildcard word positions
- three-character searches
- three-character word positions
- two-character searches
- one-character searches
疑问
该搜索行为的原因是什么?为何"whitespace-insensitive"选项无法获取文档,而"whitespace-sensitive"却可以?
原因分析
这一现象的核心在于MarkLogic对whitespace-insensitive的分词逻辑,以及通配符查询的匹配范围限制:
whitespace-insensitive的分词影响
当启用whitespace-insensitive时,MarkLogic会将文档中的空白符视为分词分隔符:
- 文档2的
09 14 012 3001会被拆分为4个独立的词:09、14、012、3001; - 文档1的
09Y14K012D3001会被视为单个完整词(Y、K、D不属于空白/标点,不会触发分词)。
而你使用的cts:word-query带通配符的查询*09*14*012*3001*是单词匹配模式——它只会查找包含连续序列09...14...012...3001的单个词:
- 文档2被拆成多个独立词,没有任何单个词包含该连续序列;
- 文档1的单个词中,Y、K、D会阻断通配符的连续匹配(
*仅匹配词内任意字符,无法跨多个独立词),因此查询无结果。
whitespace-sensitive的匹配逻辑
当设置"whitespace-sensitive"时,MarkLogic不会将空白符作为分词依据,文档2中的09 14 012 3001会被视为单个包含空白的词存入索引。此时:
- 通配符
*可以匹配词内的空白字符,因此*09*14*012*3001*能匹配文档2的这个词; - 文档1的
09Y14K012D3001作为单个词,其内部片段也能被通配符匹配,最终两个文档都能被检索到。
- 索引设置的作用
你启用的各类通配符、多字符搜索索引都能支持通配符查询,但核心矛盾还是分词规则与word-query的单词匹配限制——只要whitespace-insensitive触发了分词,就会导致跨片段的通配符匹配失败。
内容的提问来源于stack exchange,提问作者Ashish Patil
相关产品推荐
相关产品推荐

