Spring Data MongoDB聚合查询中SPEL表达式解析异常问题求助
Spring Data MongoDB聚合查询中SPEL表达式解析异常问题求助
嗨,我来帮你分析下这个问题~
首先看你遇到的报错:EL1043E: Unexpected token. Expected 'rsquare(])' but was 'comma(,)',这个错误的核心原因是SPEL解析器把MongoDB的数组语法和自身的数组表达式搞混了。
你对比下两个表达式:
- 正常工作的else分支是
{'_id': { $in: [8] } },这里的[8]是单个元素的MongoDB数组,SPEL解析时能顺利识别为参数引用并转换成MongoDB数组; - 出错的表达式里,
$or后面跟着的是包含两个嵌套文档的数组[{'accountNumber': {$regex: [10]}}, {'target.properties.NAME': {$regex: [10]}} ],SPEL看到[后,会把里面的{'accountNumber': ...}当成SPEL的代码块(SPEL中{}用于代码块),当解析到逗号时,它以为是数组元素的分隔符,但前面的代码块并没有正确闭合,所以直接抛出了“期待右括号却遇到逗号”的错误。
给你几个可行的解决方案:
方案1:将MongoDB查询块用字符串包裹,让SPEL当作字面量处理
把else分支的整个MongoDB查询转换成转义后的字符串,这样SPEL就不会去解析内部的数组和文档结构,而是直接把它交给MongoDB处理:
@Aggregation(pipeline = { // 其他聚合阶段... "?#{ [10] == null ? '{$expr: {$literal: true}}' : '{$or: [{\'accountNumber\': {$regex: '' + [10] + ''}}, {\'target.properties.NAME\': {$regex: '' + [10] + ''}} ]}' }" })
这里用'' + [10] + ''是为了把参数值嵌入到字符串中,确保正则表达式能正确引用参数。
方案2:用SPEL构造MongoDB Document对象
通过SPEL直接创建Document对象,避免语法混淆,这种方式更类型安全:
@Aggregation(pipeline = { // 其他聚合阶段... "?#{ [10] == null ? {$expr: {$literal: true}} : new org.bson.Document('$or', java.util.Arrays.asList(" + "new org.bson.Document('accountNumber', new org.bson.Document('$regex', [10]))," + "new org.bson.Document('target.properties.NAME', new org.bson.Document('$regex', [10]))" + ")) }" })
注意这里需要使用类的全限定名,确保SPEL能找到对应的类。
方案3:拆分聚合阶段,简化SPEL逻辑
如果允许的话,可以把条件判断拆分成明确的$match阶段,这样能避免复杂的SPEL嵌套,可读性更好:
@Aggregation(pipeline = { // 其他聚合阶段... "?#{ [10] == null ? '{$match: {$expr: {$literal: true}}}' : '{$match: {$or: [{\'accountNumber\': {$regex: '' + [10] + ''}}, {\'target.properties.NAME\': {$regex: '' + [10] + ''}} ]}}' }" })
你可以先试试方案1,应该能快速解决问题~
备注:内容来源于stack exchange,提问作者Yevhenii Filatov
相关产品推荐
相关产品推荐

