在Mongoose的find()中用JS的map()可行吗?为何结果一致?
关于Mongoose中find查询的两种写法疑问解答
为什么两段代码返回结果一致?
你的两段代码结果一致,核心原因是Mongoose的查询条件隐式转换逻辑:
- 你的
objectiveId字段被定义为单个ObjectId类型(而非数组类型) - 当你给这个单值字段传入数组作为查询条件时,Mongoose会自动将其转换为
$in查询,等价于{ objectiveId: { $in: 你的数组 } } - 而你写的
tracker.objectives.map((id)=>id)只是原样返回了原数组(数组元素本身就是ObjectId,map操作没做任何转换),所以最终Mongoose处理后的查询逻辑和同事推荐的$in写法完全一致
能不能在find()方法中使用map()?
当然可以。map()是JavaScript数组的原生方法,作用是生成新数组,只要通过map生成的最终值符合MongoDB/Mongoose的查询语法要求,就完全没问题。
比如需要把数组中的字符串ID转换成ObjectId时,就可以这么写:
const projectOffering = await ProjectOfferingsBudgets.find({ objectiveId: tracker.objectives.map(id => mongoose.Types.ObjectId(id)) }).lean().exec();
为什么同事说原代码不可行?
同事的说法是基于原生MongoDB驱动的逻辑:
在原生MongoDB中,{ field: [val1, val2] }会查找field字段完全等于这个数组的文档(即字段本身是数组,且和查询数组的元素、顺序完全一致),而非查找字段值在数组中的文档。
但Mongoose做了语法糖封装,自动转换了单值字段的数组查询,所以你测试时结果一致。
推荐写法
从代码可读性、兼容性和规范角度,更推荐使用$in的写法:
- 代码意图更明确,其他开发者一眼就能看懂是“匹配数组中的任意一个值”
- 不依赖Mongoose的隐式转换逻辑,避免字段类型变更(比如改成数组字段)或使用原生驱动时出现逻辑错误
- 符合MongoDB官方的标准查询语法
内容的提问来源于stack exchange,提问作者SAMRAT
相关产品推荐
相关产品推荐

