You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Groovy获取MongoDB聚合结果时出现ClassCastException问题求助

解决Groovy中MongoDB v4.x驱动AggregateIterable的GString转String类型转换异常

问题原因

MongoDB Java Sync Driver v4.x对参数类型校验更严格,Groovy的GStringImpl(双引号插值生成的字符串)与Java原生String并非同一类型。旧版驱动可能隐式处理了GString到String的转换,但新版驱动未做此兼容,导致聚合管道中传入的GString在后续结果处理时触发ClassCastException。

解决方案

核心是确保聚合管道中所有字符串参数均为Java原生String类型,可通过以下方式实现:

1. 使用Groovy单引号字符串

Groovy中单引号包裹的字符串是原生Java String,双引号则生成GString。如果不需要字符串插值,直接用单引号定义聚合阶段的操作符、字段名等:

// 正确:单引号生成Java String
def matchStage = Aggregates.match(Filters.eq('username', 'john_doe'))
def groupStage = Aggregates.group('$department', Accumulators.sum('total', 1))
def pipeline = Arrays.asList(matchStage, groupStage)

2. 显式转换GString为String

如果需要动态插值(必须用双引号),通过toString()或as String强制转换为Java String:

def userName = 'john_doe'
def departmentField = 'department'

// 方式1:调用toString()转换
def matchValue = "${userName}".toString()
def matchStage = Aggregates.match(Filters.eq('username', matchValue))

// 方式2:使用as关键字转换
def groupId = ("$${departmentField}") as String
def groupStage = Aggregates.group(groupId, Accumulators.sum('total', 1))

def pipeline = Arrays.asList(matchStage, groupStage)
def results = collection.aggregate(pipeline)
def resultList = results.toList() // 正常执行

3. 检查Document构建的聚合阶段

如果直接用Document手动构建聚合阶段,确保键和值中的字符串都是Java String:

def fieldName = 'age'
// 错误:GString作为Document的键
// def groupStage = new Document('$group', new Document("$$${fieldName}", 1))

// 正确:显式转换键为String
def groupKey = ("$$${fieldName}").toString()
def groupStage = new Document('$group', new Document(groupKey, 1))

验证方法

修改完成后,尝试调用results.toList()、results.iterator()等方法,若不再触发ClassCastException,则问题解决。

内容的提问来源于stack exchange,提问作者ionised

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:09:24