MongoDB $type 操作符

MongoDB $type 操作符完全解析

(MongoDB 8.0+,2025 年最新实践)

核心结论
$type = 查询或匹配特定 BSON 数据类型的字段**,防止类型混淆,保障数据一致性。
支持 *数字代码* 和 字符串别名 两种写法。


一、$type 基本语法

{ field: { $type: <BSON type number 或 string> } }

二、BSON 类型对照表(重点记忆!)

类型数字代码字符串别名示例
Double1"double"3.14
String2"string""hello"
Object3"object"{ name: "张三" }
Array4"array"["a", "b"]
Binary data5"binData"BinData(0, "...")
ObjectId7"objectId"ObjectId("...")
Boolean8"bool"true
Date9"date"ISODate("2025-01-01")
Null10"null"null
Regex11"regex"/^a/i
Int3216"int"42
Timestamp17"timestamp"Timestamp(1, 1)
Int6418"long"9007199254740992
Decimal12819"decimal"Decimal128("3.14")
Min key-1"minKey"MinKey
Max key127"maxKey"MaxKey

三、基本使用示例

use testdb

// 插入混杂类型数据
db.types.insertMany([
  { name: "A", age: 25 },           // age: double (1)
  { name: "B", age: "30" },         // age: string (2)
  { name: "C", age: null },         // age: null (10)
  { name: "D", age: 35 },           // age: int (16)
  { name: "E", age: true },         // age: bool (8)
  { name: "F", age: [20, 30] },     // age: array (4)
  { name: "G", age: new Date() }    // age: date (9)
])

查询 age数字 的文档(推荐)

// 方法 1:匹配 double 或 int(最常用)
db.types.find({ age: { $type: ["double", "int"] } })
// 或
db.types.find({ age: { $type: [1, 16] } })

// 方法 2:使用 $in
db.types.find({ age: { $in: [{ $type: 1 }, { $type: 16 }] } })

查询 age字符串 的文档

db.types.find({ age: { $type: "string" } })
// 或
db.types.find({ age: { $type: 2 } })

查询 agenull 的文档

db.types.find({ age: { $type: "null" } })
// 或
db.types.find({ age: null })  // 注意:这也匹配 { age: { $exists: false } }

警告{ age: null } 会匹配:

  • age: null
  • age 字段不存在
    推荐用 $type: "null" + $exists: true 精确匹配
db.types.find({ age: { $type: "null", $exists: true } })

四、高级用法

1. 查询数组中包含特定类型的元素

// scores 数组中包含 double 类型
db.students.find({
  scores: { $elemMatch: { $type: "double" } }
})

2. 查询嵌套字段类型

// address.zip 是 string
db.users.find({
  "address.zip": { $type: "string" }
})

3. 查询 ObjectId 类型

// _id 是 ObjectId(默认就是)
db.users.find({
  _id: { $type: "objectId" }
})

4. 查询 Decimal128(高精度金额)

db.transactions.find({
  amount: { $type: "decimal" }
})

五、$type 在更新中的应用

// 只更新 age 是数字的文档
db.types.updateMany(
  { age: { $type: ["double", "int"] } },
  { $inc: { age: 1 } }
)

// 将 age 是字符串的转为数字(需 $convert 或聚合)
db.types.updateMany(
  { age: { $type: "string" } },
  [
    { $set: { age: { $toInt: "$age" } } }
  ]
)

六、常见问题与解决方案

问题原因解决方案
age: null 匹配了不存在的字段null 匹配 missing{ age: { $type: "null", $exists: true } }
想查“数字”但漏了 int只查了 double[1, 16]["double", "int"]
$type: 2 没匹配到字段是 number 但实际是 int明确类型
查询慢无索引为频繁查询字段建索引

七、性能建议:建索引

// 为 age 字段建索引(支持 $type 查询)
db.types.createIndex({ age: 1 })

// 复合索引
db.users.createIndex({ status: 1, createdAt: 1 })

注意$type 查询在有索引时仍需扫描,但可配合其他字段加速。


八、GUI 工具使用 $type

工具操作
MongoDB CompassFilter → { age: { $type: "string" } }
MongoDB AtlasAggregations → $match: { age: { $type: 1 } }
VS Code直接输入 JSON 过滤

九、完整实战脚本

// type_demo.js
use demo

// 插入测试数据
db.mixed.insertMany([
  { item: "A", qty: 10 },           // double
  { item: "B", qty: "20" },         // string
  { item: "C", qty: null },         // null
  { item: "D", qty: 30 },           // int
  { item: "E", qty: [1, 2, 3] },    // array
  { item: "F", qty: true },         // bool
  { item: "G", qty: new Date() }    // date
])

print("=== $type 查询示例 ===\n")

// 1. qty 是数字(double 或 int)
print("1. 数字类型 (double/int):")
db.mixed.find({ qty: { $type: ["double", "int"] } })
  .projection({ item: 1, qty: 1, _id: 0 })
  .forEach(printjson)

// 2. qty 是字符串
print("\n2. 字符串类型:")
db.mixed.find({ qty: { $type: "string" } })
  .projection({ item: 1, qty: 1, _id: 0 })
  .forEach(printjson)

// 3. qty 是 null 且字段存在
print("\n3. null 类型(字段存在):")
db.mixed.find({ qty: { $type: "null", $exists: true } })
  .projection({ item: 1, qty: 1, _id: 0 })
  .forEach(printjson)

// 4. 统计各种类型数量
print("\n4. 类型统计:")
db.mixed.aggregate([
  { $group: {
      _id: { $type: "$qty" },
      count: { $sum: 1 }
  }},
  { $sort: { count: -1 } }
]).forEach(d => print(`${d._id}: ${d.count} 条`))

运行:

mongosh type_demo.js

十、一句话总结

**“$type = 精确匹配字段 **BSON 类型,防止 25'25' 混淆,保障数据一致性”


快速 $type 模板

// 数字(推荐)
{ field: { $type: ["double", "int"] } }

// 字符串
{ field: { $type: "string" } }

// null(字段存在)
{ field: { $type: "null", $exists: true } }

// 数组
{ field: { $type: "array" } }

// ObjectId
{ _id: { $type: "objectId" } }

官方文档
https://www.mongodb.com/docs/manual/reference/operator/query/type/


如需 批量转换类型Schema 验证 + $type从 SQL 类型映射实时监控类型异常,欢迎继续提问!

文章已创建 2349

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部