Spring Mongo Template:如何不转换值用字符串匹配任意类型字段?
解决方案:用字符串匹配MongoDB中任意类型的字段值
好问题!你的需求完全可行,不过之前的思路走偏了——Spring Data MongoDB里的type()方法是用来筛选字段本身的数据类型的(比如type(2)表示只匹配Integer类型的字段),而不是用来实现“字符串值匹配不同类型字段”的逻辑,所以你之前的写法相当于要求字段既是某个类型,又等于字符串"31",自然查不到结果。
下面给你两种实用的解决思路:
1. 明确枚举可能的类型,用$or做或查询
如果你能预判字段可能的类型(比如Integer、String、Long),可以直接用orOperator把不同类型的匹配条件组合起来:
Query query = new Query(); Criteria matchAnyType = new Criteria().orOperator( where("department.departmentId").is("31"), // 匹配String类型的"31" where("department.departmentId").is(31), // 匹配Integer类型的31 where("department.departmentId").is(31L) // 匹配Long类型的31 ); query.addCriteria(matchAnyType);
这种方式简单直接,兼容性好,适合字段类型范围明确的场景。
2. 用MongoDB表达式自动转换字段类型(推荐)
如果字段类型不确定,想要更灵活的匹配,可以利用MongoDB的$expr和$toString操作符,把字段值统一转成字符串后再和输入的字符串匹配:
import org.bson.BasicDBObject; import java.util.Arrays; // ... Query query = new Query( where("department.departmentId").expr( new BasicDBObject("$eq", Arrays.asList( new BasicDBObject("$toString", "$department.departmentId"), // 把字段值转成字符串 "31" // 匹配输入的字符串 )) ) );
这个方法会自动把字段的Integer、Long、Double等类型值转成字符串,再和"31"做匹配,完美符合你“不用转换输入值、匹配任意类型字段”的需求。
注意:
$toString是MongoDB 4.0及以上版本才支持的特性,如果你的MongoDB版本较低,可能需要考虑升级,或者用$concat等替代方案(比如$concat: ["$department.departmentId", ""]来隐式转字符串)。
总结一下:你的需求完全可以实现,核心是利用MongoDB的查询表达式来做类型转换匹配,而不是误用Spring Data的type()方法。
内容的提问来源于stack exchange,提问作者Mark Smith
相关产品推荐
相关产品推荐

