如何编写可被cts.parse解析的搜索语法以生成嵌套cts.jsonPropertyScopeQuery?
问题:使用
cts.parse生成嵌套cts.jsonPropertyScopeQuery的语法错误 目标是生成嵌套范围查询:
cts.jsonPropertyScopeQuery("status", cts.jsonPropertyScopeQuery("current", cts.jsonPropertyValueQuery("status", "Received", ["lang=en"], 1)))
先从单层范围查询cts.jsonPropertyScopeQuery("current", cts.jsonPropertyValueQuery("status", "Received", ["lang=en"], 1))入手,编写了以下JavaScript代码,试图通过cts.parse结合自定义绑定函数实现:
'use strict'; let bindingsObject = { Scope: scope, StatusValue: statusValue, }; function scope(operator, value, options) { let theProperty = fn.substringBefore(value, ":"); let thePropertyTrimmed = theProperty.substring(1); let theRest = fn.substringAfter(value, ":"); let theRestTrimmed = theRest.substring(0, theRest.length - 1); return cts.jsonPropertyScopeQuery(thePropertyTrimmed, cts.parse(theRestTrimmed, bindingsObject)); } function statusValue(operator, value, options) { return cts.jsonPropertyValueQuery('status', value, ['exact']); } //cts.parse('(StatusValue:Received)', bindingsObject) cts.parse('(Scope:(current:(StatusValue:Received)))', bindingsObject)
执行时触发错误:
[javascript] XDMP-UNEXPECTED: cts.parse('(Scope:(current:(StatusValue:Received)))', bindingsObject) -- Unexpected token syntax error, unexpected PLpar_
需要了解cts.parse可解析的、用于生成jsonPropertyScopeQuery的正确搜索语法。
原因与解决方案
语法解析逻辑问题
cts.parse的查询字符串语法不支持你写的Scope:(current:(StatusValue:Received))这种嵌套括号结构——自定义绑定函数的参数只能是单一值或符合基础查询语法的字符串,不能是嵌套的括号表达式,这种写法会触发解析器的语法错误。
正确实现方式
方法1:调整绑定函数的参数格式
把范围属性和内部查询用分隔符(比如|)拆分,让绑定函数能正确识别参数,避免嵌套括号:
'use strict'; let bindingsObject = { Scope: scope, StatusValue: statusValue, }; function scope(operator, value, options) { // 用|拆分属性名和内部查询字符串 const [propName, innerQueryStr] = value.split('|'); return cts.jsonPropertyScopeQuery(propName, cts.parse(innerQueryStr, bindingsObject)); } function statusValue(operator, value, options) { return cts.jsonPropertyValueQuery('status', value, ['lang=en'], 1); } // 单层范围查询测试 // cts.parse('Scope:current|StatusValue:Received', bindingsObject) // 生成目标嵌套查询 cts.parse('Scope:status|Scope:current|StatusValue:Received', bindingsObject)
方法2:直接使用MarkLogic内置的范围查询语法
MarkLogic的搜索语法本身支持JSON属性路径,不需要自定义绑定函数,直接用层级属性写法就能实现多层范围查询:
- 单层范围查询(匹配
current.status = "Received"):
cts.parse('current.status:Received', { options: ['lang=en'] })
- 嵌套目标查询(匹配
status.current.status = "Received"):
cts.parse('status.current.status:Received', { options: ['lang=en'] })
如果需要更精确的范围控制,也可以直接嵌套调用cts.jsonPropertyScopeQuery,完全不需要通过cts.parse:
cts.jsonPropertyScopeQuery( "status", cts.jsonPropertyScopeQuery( "current", cts.jsonPropertyValueQuery("status", "Received", ["lang=en"], 1) ) )
关键说明
cts.parse遵循MarkLogic内置的搜索字符串语法规则,自定义绑定函数的参数是解析后的单一值,不能传入嵌套的查询表达式。- 内置的属性路径语法(如
a.b.c:value)本质就是多层jsonPropertyScopeQuery的简化写法,能满足绝大多数嵌套范围查询需求。
内容的提问来源于stack exchange,提问作者David Steiner
相关产品推荐
相关产品推荐

