You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js用OR条件查询MongoDB报参数需为12字节Buffer或24位十六进制串错误如何解决

错误原因

你代码中无论传入的id是什么格式,都会强制调用ObjectId(id)做转换,而MongoDB的ObjectId要求输入必须是12字节的Buffer、或者24位十六进制字符串,你自定义的ownerId(比如示例中的b0jytaonktsc5ghf)不符合这个格式,转换逻辑直接抛出错误,还没有执行到数据库查询步骤。
因为$or条件的所有参数会先完成预处理再执行查询,所以哪怕你实际要匹配的是ownerId字段,只要ObjectId(id)转换失败,就会直接触发报错。

解决方法

先判断传入的id是否符合ObjectId格式,只有符合格式时才添加_id的查询条件,不符合时只查询ownerId字段即可,修正后的代码如下:

var ObjectId = require("mongodb").ObjectId;

const getDetailById = async (req, res) => {
  const { id } = req.params;
  try {
    // 构造查询条件
    const query = { $or: [] };
    // ownerId是字符串类型,直接加查询条件
    query.$or.push({ ownerId: id });
    // 只有id符合ObjectId格式时,才加_id的查询条件
    if (ObjectId.isValid(id)) {
      query.$or.push({ _id: ObjectId(id) });
    }
    let detail = await Task.find(query).populate("shop");
    // 注意补全查询成功后的响应返回逻辑
    res.json(detail);
  } catch (err) {
    sendError(401, "Cannot get detail by given id", err.message, req, res);
  }
};
额外注意项

你当前的Schema定义存在隐性bug:ownerId的默认值写的是default: uniqid(),会在服务启动时就执行一次uniqid()生成固定值,后续所有新增数据的ownerId都会重复,应该改成default: uniqid,传入函数本身,让Mongoose在每次新增数据时再调用生成唯一值。

内容的提问来源于stack exchange,提问作者user16041868

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:15:02