隐式 AND 与 $and
过滤文档中同一层级的多个键之间天然是 AND 关系,MongoDB 只返回同时满足全部条件的文档。$and 是显式写法,主要用于两类情况:同一字段需要多个条件(JavaScript 对象禁止重复键名),以及需要把 (A 或 B) 与 C 组合在一起表达逻辑分组。条件的实际执行顺序由查询优化器决定,与书写先后无关。
基本信息
| 隐式写法 | { status: "paid", qty: 2 } |
|---|---|
| 显式写法 | { $and: [ { qty: { $gte: 1 } }, { qty: { $lte: 10 } } ] } |
| 同族操作符 | $or、$nor、$not、$expr |
| 适用版本 | MongoDB 3.6+ 行为一致 |
示例
示例
// 隐式 AND:三个条件必须同时成立
db.orders.find({ status: "paid", "items.sku": "A-1", qty: 2 })
// 同一字段的范围条件必须用 $and 表达
db.orders.find({ $and: [ { qty: { $gte: 1 } }, { qty: { $lte: 10 } } ] })
// 把"或"条件与普通条件组合:(status) 且 (qty 为 0 或 qty 大于 100)
db.orders.find({ status: "paid", $and: [ { $or: [ { qty: 0 }, { qty: { $gt: 100 } } ] } ] })
// 跨字段比较交给 $expr
db.orders.find({ status: "paid", $expr: { $gte: ["$paid", "$amount"] } })典型使用场景
- 多维度过滤:状态、渠道、SKU 并列时直接用隐式 AND,最短最清楚
- 同字段区间:数量大于等于 1 且小于等于 10,必须用 $and 包两个条件
- 逻辑分组:把或条件嵌入与条件中,表达"某状态且落在异常区间"
- 跨字段比较:用 $expr 比较两个字段,通常与普通条件并列在同一层
- SQL 迁移:WHERE a AND b 直接映射为同层级键
- 数组内多条件:对同一数组字段既要匹配元素 A 又要匹配元素 B,需要用 $and 分两次写
逻辑操作符对照
| 写法 | 语义 | 典型用途 |
|---|---|---|
| {a:1,b:2} | 隐式 AND | 多字段等值过滤 |
| $and:[...] | 数组内全部成立 | 同字段多条件、显式分组 |
| $or:[...] | 数组内任一成立 | 多个备选条件 |
| $nor:[...] | 数组内全部不成立 | 排除若干组合 |
优化器在计划选择阶段会并行试跑多个候选计划再挑最快的,因此条件顺序不影响正确性,也不保证"写在前面先执行";判断某字段是否用上索引要看 explain 的 winningPlan,而不是把条件调整到前面。
$and 也常用于把 $expr 与其他条件并列,或让执行计划提示(hint、索引交集)有明确的字段组合;纯等值多字段场景用隐式写法即可。