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

Kotlin环境下MongoDB Criteria的$in操作符异常问题确认

Spring Data MongoDB $in查询嵌套数组问题解决

问题现象

使用Spring Data MongoDB的Criteria构建or组合查询时,调用in()方法传入List参数,生成的MongoDB查询语句中$in条件出现嵌套数组([["toto"]]),导致查询无结果:

val names = mutableListOf("toto")
Criteria().orOperator(
    mutableListOf(
        Criteria("fieldA.name").`in`(names),
        Criteria("fieldB.name").`in`(names)
    )
)

日志显示的错误查询语句:

Executing count: { "$or" : [{ "fieldA.urn" : { "$in" : [["toto"]]}}, { "fieldB.urn" : { "$in" : [["toto"]]}}]} in collection: fields

但改用is()方法传入单个元素时,查询正常返回结果:

Criteria().orOperator(
    mutableListOf(
        Criteria("fieldA.name").`is`(names[0]),
        Criteria("fieldB.name").`is`(names[0])
    )
)

该问题存在于以下版本:

  • org.springframework.boot:spring-boot-starter-data-mongodb:2.7.9
  • org.springframework.data:spring-data-mongodb:3.4.8
  • org.mongodb:mongodb-driver-core:4.10.2

原因

这是Spring Data MongoDB的框架bug:当in()方法接收List类型参数,且处于orOperator等组合查询场景时,框架会错误地将外层List再次包装为数组,生成不符合MongoDB规范的嵌套数组条件。MongoDB的$in仅接受单层数组作为匹配值,因此嵌套数组无法匹配任何数据。

解决方法

方法1:将List转为可变参数传入

利用Kotlin的*运算符把List展开为可变参数,避免框架重复包装:

val names = mutableListOf("toto")
Criteria().orOperator(
    mutableListOf(
        Criteria("fieldA.name").`in`(*names.toTypedArray()),
        Criteria("fieldB.name").`in`(*names.toTypedArray())
    )
)

方法2:使用inValues()替代in()

inValues()方法专门针对集合类型参数设计,不会产生嵌套数组问题:

val names = mutableListOf("toto")
Criteria().orOperator(
    mutableListOf(
        Criteria("fieldA.name").inValues(names),
        Criteria("fieldB.name").inValues(names)
    )
)

方法3:升级框架版本

该bug已在Spring Data MongoDB 3.4.9及以上版本修复,对应Spring Boot版本为2.7.10及以上,升级后即可直接使用原写法正常生成查询语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:43:20