MongoDB Java使用Filters.in查询嵌套对象返回空的问题及解决方案
问题根源
你遇到的是MongoDB自定义对象的匹配逻辑和Java内存匹配逻辑不一致的问题,核心差异如下:
Filters.in直接传入自定义对象列表时,MongoDB驱动会先将列表里的MongodbSpecificationEntryPointer序列化为BSON结构,再和数据库中存储的specificiationEntryPointer字段做全字段、全结构精确匹配,字段顺序、字段值类型、字段数量任意一项不一致都会匹配失败- 你内存过滤逻辑用的是Java
List.contains()方法,该方法依赖你在MongodbSpecificationEntryPointer类中覆写的equals()方法判断匹配性,和数据库层面的BSON匹配逻辑完全无关,因此会出现内存过滤有结果、数据库查询无结果的差异
另外还有一个高频排查点:你定义的字段常量FIELD_SPECIFICATION_ENTRY_POINTER拼写为specificiationEntryPointer,比标准拼写specificationEntryPointer多了一个i,需先确认和数据库中实际存储的字段键名完全一致。
正确实现方案
有两种常用的高性能实现方案,优先选择第一种:
方案1:按对象唯一标识字段查询(推荐)
如果MongodbSpecificationEntryPointer存在唯一业务主键/数据库主键,直接提取所有主键值,查询嵌套字段即可,该方案性能最高、兼容性最强:
// 先提取所有指针对象的唯一ID List<Object> pointerIdList = specificiationEntryPointerList.stream() .map(MongodbSpecificationEntryPointer::getId) .toList(); // 查询嵌套的id字段是否在列表中 Bson filter = Filters.in(PrdVersionOverviewDbData.FIELD_SPECIFICATION_ENTRY_POINTER + ".id", pointerIdList);
方案2:全对象精确匹配
如果业务要求必须匹配对象的所有字段,先确认以下两点保证序列化后BSON完全一致:
MongodbSpecificationEntryPointer类的所有字段都配置了正确的@BsonProperty注解,没有多余的瞬态字段,字段序列化顺序和数据库存储的字段顺序一致- 所有字段的序列化后类型和数据库存储的BSON类型完全匹配,比如数值类型不要出现Java Long序列化后变成BSON Int32的情况
确认后就可以直接使用你原来的in查询写法,就能正常返回结果。
内容的提问来源于stack exchange,提问作者Kira Resari
相关产品推荐
相关产品推荐

