$exists 与 $type 是什么
$exists 判断字段是否存在,注意值为 null 的字段也算存在;$type 按 BSON 类型过滤文档,可以写类型别名(string、int、double、bool、array、object、date、objectId 等),也可以写数字码,还支持传数组同时匹配多种类型。别名 number 一次覆盖 int、long、double、decimal 四种数值类型。两者都是文档级判断,绝大多数情况下用不上索引,集合越大开销越明显,属于排障与巡检工具而不是在线查询的常规手段。
基本信息
| 判断存在 | { err: { $exists: true } } |
|---|---|
| 判断缺失 | { err: { $exists: false } } |
| 按类型 | { value: { $type: "string" } } |
| 多类型 | $type: ["int", "double"] |
| 数值别名 | number 覆盖 int / long / double / decimal |
| 索引情况 | 多数写法无法走索引,属重操作 |
典型使用场景
- 数据质量巡检:找出缺失关键字段的脏数据并统计数量
- 版本兼容期:新旧结构并存时按字段是否存在分流处理
- 类型排查:同名字段有些写成字符串有些是数字,定位写入方不一致
- 清理遗留字段:列出仍带有已废弃字段的文档,安排回填或删除
- 实验分析:把带某个实验标记的文档单独拉出来对比
常见写法
常见写法
db.logs.find({ err: { $exists: true } }) // 有 err 字段的文档
db.logs.find({ err: { $exists: false } }) // 完全没有该字段
db.metrics.find({ value: { $type: "string" } }) // 值被误写成字符串
db.metrics.find({ value: { $type: ["int", "double"] } }) // 只要数值类型
db.metrics.find({ value: { $type: "number" } }) // 四种数值类型一次覆盖
db.users.find({ tags: { $type: "array" } }) // 字段是数组形态
db.users.countDocuments({ email: { $exists: false } }) // 巡检:统计缺失数写法对照
| 写法 | 含义 | 注意 |
|---|---|---|
| $exists: true | 字段存在(含值为 null) | 与 $ne: null 语义不同 |
| $exists: false | 字段不存在 | 无法有效利用索引 |
| $type: "string" | 按类型匹配 | 数组含该类型元素也会命中整条文档 |
| $type: ["int","double"] | 多类型匹配 | 列表过长会让判断变慢 |
| $type: "number" | 四种数值类型 | 做数值校验时比逐个列举省事 |
对数组字段用 $type 是元素级判断:数组里只要有一个字符串元素,$type: "string" 就会命中整条文档,解读结果时要留意,聚合里想精确到元素可以用 $filter。
$exists: true 与 { field: { $ne: null } } 不等价:前者包含值为 null 的文档,后者会把 null 排除在外。