Node.js+Express多数据类型搜索API创建及类型转换错误解决
解决多数据类型搜索API的类型转换错误
问题原因
你的phone字段是Number类型,但req.params.key是字符串类型,MongoDB执行$regex匹配时会尝试把字符串类型的搜索值转成数字,当搜索关键词包含非数字字符(比如"abc")时,转换失败就会抛出CastError。
解决方案
方案1:用$expr将数字字段转为字符串后匹配
利用MongoDB的$expr和$toString操作符,把Number类型的phone字段转换成字符串再做正则匹配,无需转换输入值,也不会触发类型错误:
const searchKey = req.params.key; const user = await User.find({ $or: [ { name: { $regex: searchKey, $options: 'i' } }, // 可选:加i忽略大小写 { email: { $regex: searchKey, $options: 'i' } }, { $expr: { $regexMatch: { input: { $toString: "$phone" }, regex: searchKey, options: 'i' // 可选:忽略大小写 } } } ] });
方案2:动态判断关键词类型,分条件查询
先判断搜索关键词是否为纯数字,再构造对应查询条件,避免不必要的类型转换:
const searchKey = req.params.key; const orConditions = [ { name: { $regex: searchKey, $options: 'i' } }, { email: { $regex: searchKey, $options: 'i' } } ]; // 判断是否为纯数字字符串 const isNumeric = !isNaN(parseFloat(searchKey)) && isFinite(searchKey); if (isNumeric) { // 数字关键词:同时支持精确匹配数字、模糊匹配转字符串后的手机号 orConditions.push( { phone: parseInt(searchKey) }, { $expr: { $regexMatch: { input: { $toString: "$phone" }, regex: searchKey, options: 'i' } } } ); } else { // 非数字关键词:仅对手机号做字符串转换后的模糊匹配 orConditions.push({ $expr: { $regexMatch: { input: { $toString: "$phone" }, regex: searchKey, options: 'i' } } }); } const user = await User.find({ $or: orConditions });
方案3:修改数据结构(可选)
如果业务允许,把phone字段改为String类型存储,所有字段统一用字符串正则匹配,彻底避免类型问题:
// 定义Schema时修改phone类型 const userSchema = new mongoose.Schema({ name: String, phone: String, // 从Number改为String email: String });
注意事项
- 正则匹配默认区分大小写,可通过
$options: 'i'开启忽略大小写,根据业务需求选择。 - 大规模数据下正则匹配可能影响性能,建议结合MongoDB文本索引优化查询效率。
内容的提问来源于stack exchange,提问作者htyagi1
相关产品推荐
相关产品推荐

