Node.js中使用Mongoose的findOne查询数值字段返回null如何解决
问题根因
你导入数据时的操作导致数据库中codigo_producto字段实际存储的是字符串类型,和Mongoose模型定义的Number类型不匹配,导致查询失效:
csvtojson读取CSV文件时,所有字段默认解析为字符串类型- 你导入数据时直接使用MongoDB原生的
collection.insertMany插入,没有经过Mongoose模型的类型转换,所以数值类型的字段全部以字符串格式存入了数据库 - 当你用Mongoose查询时,因为Schema定义
codigo_producto为Number类型,无论你传入数字还是字符串作为查询值,Mongoose都会自动将查询条件转为Number类型,和数据库中存储的字符串类型字段永远无法匹配,所以始终返回null
验证方法
你可以直接进入MongoDB Shell执行以下命令,确认字段类型:
# 查看是否存在codigo_producto为字符串类型的记录 db.db_productos.find({"codigo_producto": {$type: "string"}})
如果执行后返回了你插入的记录,就可以确认是类型不匹配的问题。
解决方案
步骤1:清理已插入的错误数据
在MongoDB Shell执行:
db.db_productos.deleteMany({})
步骤2:修改导入代码,确保类型正确
推荐优先使用Mongoose模型插入数据,会自动按Schema做类型转换,无需手动处理:
csvtojson().fromFile("./public/upload/productos.csv").then(async source => { var results = []; for (var i = 0; i < source.length; i++) { var linea = { codigo_producto: source[i]["codigo_producto"], nombre_producto: source[i]["nombre_producto"], nitproveedor: source[i]["nitproveedor"], precio_compra: source[i]["precio_compra"], ivacompra: source[i]["ivacompra"], precio_venta: source[i]["precio_venta"] }; results.push(linea); } // 直接用Mongoose模型的insertMany方法,自动按Schema转换类型 await Productos.insertMany(results, {ordered:false}); console.log("导入成功"); }).catch(err => console.log(err));
如果你坚持使用原生collection插入,需要手动将数值字段转为Number类型:
var linea = { codigo_producto: Number(source[i]["codigo_producto"]), nombre_producto: source[i]["nombre_producto"], nitproveedor: Number(source[i]["nitproveedor"]), precio_compra: source[i]["precio_compra"], ivacompra: Number(source[i]["ivacompra"]), precio_venta: Number(source[i]["precio_venta"]) };
步骤3:重新导入数据后查询
重新执行导入逻辑后,再执行以下查询即可正常返回结果:
const products = await Productos.findOne({ codigo_producto: 2 }); console.log(products);
内容的提问来源于stack exchange,提问作者Juan Galofre
相关产品推荐
相关产品推荐

