NodeJS+MongoDB查询设置字段排除仍返回完整结果
问题原因分析
你遇到的问题根源在于MongoDB Node.js驱动版本与你参考的示例语法不匹配。在你使用的旧版本驱动(对应MongoDB 3.0.1)中,find()方法的参数规则和现代版本有差异:
- 现代驱动(比如MongoDB 4.x+对应的驱动)允许把投影对象直接作为
find()的第二个参数 - 但在你当前的旧驱动里,
find()的第二个参数是查询条件,而非投影!投影需要通过第三个参数的配置对象来指定,否则你的投影设置会被驱动完全忽略,自然会返回包含_id的完整文档,甚至混合0和1的错误投影也不会触发报错——因为驱动根本没把这个参数当成投影来解析。
解决方案
下面是两种适配你当前环境的修正写法:
方法1:使用第三个参数指定投影(适配旧驱动)
把投影配置放到find()的第三个参数的projection属性中:
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/"; MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("mydb"); // 投影作为第三个参数的projection属性 dbo.collection("customers").find({}, {}, { projection: { _id: 0, name: 1, address: 1 } }) .toArray(function(err, result) { if (err) throw err; console.log(result); db.close(); }); });
方法2:使用链式project()方法(更直观,兼容旧版本)
通过project()方法单独指定投影,这种写法在新旧驱动中都能正常工作:
var MongoClient = require('mongodb').MongoClient; var url = "mongodb://localhost:27017/"; MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("mydb"); dbo.collection("customers").find({}) .project({ _id: 0, name: 1, address: 1 }) // 单独指定投影 .toArray(function(err, result) { if (err) throw err; console.log(result); db.close(); }); });
补充说明
关于你提到的「混合name:0和_id:0不报错」的问题:因为你的投影对象被当成了查询条件(空查询的补充,实际无意义),MongoDB根本没接收到投影指令,所以不会触发投影规则的校验(MongoDB要求投影只能全是包含1或者全是排除0,除了_id可以例外)。
内容的提问来源于stack exchange,提问作者donkey
相关产品推荐
相关产品推荐

