mongodb中$size仅支持精确匹配数组长度,如{"tags":{"$size":3}};范围查询需用$expr+聚合表达式,如{"$expr":{"$gt":[{"$size":"$items"},5]}};$size不支持索引,高频查询应冗余计数字段。

用 $size 查询数组字段的精确长度
MongoDB 不支持直接用 $gt、$lt 比较数组长度,必须用 $size 操作符——但它只支持「等于」匹配,不能做范围判断。
比如查 tags 数组恰好有 3 个元素的文档:
{ "tags": { "$size": 3 } }
常见错误是写成 { "tags": { "$size": { "$gt": 2 } } },这会报错 Operator $size requires a number, got object。
-
$size的值必须是整数,不能是表达式或其它操作符 - 如果数组字段不存在或为
null,该文档不会被匹配($size不会将其视为空数组) - 索引对
$size查询无效,无法利用tags上的索引加速
查数组长度大于/小于某个值?得用 $expr + $size
从 MongoDB 3.6 起,$expr 允许在查询条件中使用聚合表达式,这才真正支持长度比较。
查 items 数组长度大于 5:
一款AI工具,主要用于Monitor and clean up invalid Codex authentication files in CPA. Check quota status, disable files returning 401 errors, and perform dual verification before deletion.,适合需要提升相关任务效率的用户。
{ "$expr": { "$gt": [{ "$size": "$items" }, 5] } }
查长度不为 0(即非空数组):
{ "$expr": { "$ne": [{ "$size": "$items" }, 0] } }
-
$size在$expr中可与$gt、$gte、$lt、$ne等组合,但不能用于$in或正则 - 字段名必须带
$前缀(如"$items"),否则会被当作字面量字符串 - 如果
items字段缺失或不是数组,$size返回null,整个表达式结果为false,文档不匹配
性能和建模提醒:别让数组长度成为高频查询条件
用 $expr 查长度本质是全集合扫描(即使字段有索引),因为 $size 需要实时计算每个文档的数组长度。
- 如果频繁按长度筛选(比如「至少选了3个标签的用户」),建议冗余一个
tags_count字段,在应用层维护其值 - 更新数组时(
$push、$pull),同步用$inc更新计数字段,避免查时再算 - 对超大集合(千万级+),
$expr + $size查询可能秒变慢查询,务必在测试环境压测
数组字段为空或不存在?$exists 和 $type 得配合用
$size: 0 只能匹配明确存了空数组 [] 的文档,对字段缺失或存 null 的情况无感。
想查「数组字段存在且非空」,得组合判断:
{ "items": { "$exists": true, "$ne": [], "$type": "array" } }
-
"$exists": true排除字段缺失的文档 -
"$ne": []排除空数组(注意:不能只靠这个,因为null也满足$ne: []) -
"$type": "array"确保字段值确实是数组类型,把null、字符串、对象等都过滤掉
实际业务里,字段语义是否允许 null 或缺失,直接影响这几个条件要不要同时写全。漏掉一个,就可能查出意料之外的数据。










