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

MongoDB如何通过子字符串匹配查询ObjectId类型的_id字段

MongoDB 按_id子串匹配的正确实现方式

默认情况下MongoDB集合的_id字段是ObjectId类型,属于BSON独立对象类型,并非字符串类型,而$regex正则操作符仅支持对字符串类型字段做匹配,因此你写的查询语句{_id: {$regex: '62a0ed7'}}无法拿到预期结果。

可落地的实现方案

方案1:前缀匹配优先用范围查询(性能最高,生产环境推荐)

如果你要匹配的是_id的前缀子串(比如示例里要找开头包含62a0ed7的_id),不需要做全表正则,直接构造ObjectId的范围区间即可,能直接命中_id的默认索引,查询速度极快:

// 替换成你要匹配的子串
const matchPrefix = "62a0ed7"
// 构造区间上下界
const lowerBound = ObjectId(matchPrefix.padEnd(24, "0"))
const upperBound = ObjectId(matchPrefix.padEnd(24, "f"))

// 执行查询
db.你的集合名称.find({
  _id: {
    $gte: lowerBound,
    $lt: upperBound
  }
})

注意:该方案仅适用于前缀匹配场景,无法匹配_id中间、末尾位置的子串。

方案2:任意位置子串匹配(MongoDB 4.4+版本)

4.4及以上版本支持在$expr中使用聚合正则运算符,直接在查询阶段把_id转为字符串后做匹配,写法更简洁:

db.你的集合名称.find({
  $expr: {
    $regexMatch: {
      input: { $toString: "$_id" }, // 将ObjectId类型的_id转为字符串
      regex: "62a0ed7" // 你要匹配的子串
    }
  }
})

方案3:任意位置子串匹配(MongoDB 4.4以下旧版本)

旧版本不支持在$expr中直接用正则匹配,可以通过聚合管道先转字符串再匹配:

db.你的集合名称.aggregate([
  // 第一步:把_id转成字符串存为临时字段
  {
    $addFields: {
      tmpIdStr: { $toString: "$_id" }
    }
  },
  // 第二步:对临时字符串字段做正则匹配
  {
    $match: {
      tmpIdStr: { $regex: "62a0ed7" }
    }
  },
  // 第三步:去掉临时字段,返回原始文档结构
  {
    $project: {
      tmpIdStr: 0
    }
  }
])

性能注意事项

所有需要将ObjectId转为字符串再做正则匹配的查询,都无法命中_id的默认索引,集合数据量较大时会触发全表扫描,性能很差。如果业务中频繁需要按_id的子串做查询,建议写入文档时就冗余一个字符串类型的_id字段,给该字段建立索引后再做正则查询,能大幅提升查询效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 06:39:32