MarkLogic大小写不敏感查询结果异常问题求助
嘿,我来帮你捋捋你遇到的这个查询问题——明明觉得不该匹配的文档,结果却被返回了,核心原因其实是MarkLogic处理空白类字符的规则和你预期的不一样,咱们一步步拆解修复:
为啥会出现这个意外?
先看你文档里的endPointName值:
<endPointName>Oracle RMS 9_RMS 9 Pos and Allocations</endPointName>
注意这里是下划线_把9和RMS隔开的,但你的查询字符串用的是空格:"Oracle RMS 9 RMS 9 POs and Allocations"。
当你用cts:element-value-query并指定("case-insensitive","whitespace-sensitive")时,MarkLogic的索引规则里,下划线属于“类空白字符”,会被自动当作空格处理。所以文档里的9_RMS在索引时会被转成9 RMS,刚好和你查询里的对应部分对上,这就导致本来不该匹配的文档被找出来了。
怎么修复?
要实现严格的字符匹配(区分下划线和空格),有两个靠谱的方案:
方案1:用exact替换whitespace-sensitive
把查询里的选项换成("case-insensitive","exact"),这个选项会严格对比每一个字符,包括下划线和空格的区别,同时还保留大小写不敏感的需求:
cts:uris((),(), cts:and-query(( cts:collection-query("workflow"), cts:element-value-query( xs:QName("endPointName"), "Oracle RMS 9 RMS 9 POs and Allocations", ("case-insensitive","exact") ) )) )
这样一来,文档里的下划线和查询里的空格不匹配,就会返回你预期的空序列了。
方案2:用cts:element-word-query做精确词匹配
如果你的场景更偏向词级别的精确匹配,也可以换成cts:element-word-query,搭配exact选项同样能实现严格匹配:
cts:uris((),(), cts:and-query(( cts:collection-query("workflow"), cts:element-word-query( xs:QName("endPointName"), "Oracle RMS 9 RMS 9 POs and Allocations", ("case-insensitive","exact") ) )) )
不过这个方案更适合拆分词的场景,如果你是要整值完全匹配,方案1更直接。
额外提醒:检查数据库索引配置
如果换了选项还是有问题,记得确认下你的数据库是否启用了元素值索引(Element Value Index),并且索引的归一化规则没有特殊处理下划线。不过一般默认配置下,exact选项会绕过索引的归一化,直接做字符精确对比,所以大概率用方案1就解决问题了。
内容的提问来源于stack exchange,提问作者marklogic_coder

