首页 / MongoDB 入门教程 / 数组查询

MongoDB 入门教程

数组查询

本教程共 50 篇 · 第 17 篇 · 更新于 2026-07-30 · 约 8 分钟阅读

MongoDBMongoDB 入门教程数组查询$all$elemMatch$size

17. 数组查询

本节目标:掌握针对数组字段的查询——怎么匹配「包含全部」「按条件匹配某个元素」「按长度」以及「不含某些值」。

17.1 准备带数组的数据

本章用 userstags 数组,以及新建 orders(商品明细是文档数组)来演示。先建 orders

db.orders.insertMany([
  {
    _id: 1001,
    user_id: 1,
    items: [
      { product: "键盘", qty: 1, price: 199 },
      { product: "鼠标", qty: 2, price: 89 }
    ],
    total: 377,
    status: "paid",
    created_at: ISODate("2024-01-20")
  },
  {
    _id: 1002,
    user_id: 2,
    items: [
      { product: "显示器", qty: 1, price: 1299 }
    ],
    total: 1299,
    status: "pending",
    created_at: ISODate("2024-02-11")
  },
  {
    _id: 1003,
    user_id: 1,
    items: [
      { product: "键盘", qty: 3, price: 199 }
    ],
    total: 597,
    status: "paid",
    created_at: ISODate("2024-03-05")
  }
])

users 沿用第 13 章那 5 条,外加第 16 章为演示 $exists 插入的第 6 条(其 tags["new"])。

17.2 隐式包含匹配

最基础的:数组字段直接写值,表示「数组里包含这个值即可」:

// tags 数组里包含 "vip" 的用户(不论位置)
db.users.find({ tags: "vip" }).pretty()

这条会命中张伟、王芳、陈强。

17.3 $all:包含全部元素

$all 要求数组同时含有列表里的每一个值:

// tags 同时包含 vip 和 gamer
db.users.find({ tags: { $all: ["vip", "gamer"] } }).pretty()

只有张伟的 tags["vip", "gamer"],所以只命中他。

Tip

$all 不要求顺序,也不要求只有这些。只要「都有」就匹配。

17.4 $size:按数组长度匹配

$size 按数组元素个数筛选:

// tags 恰好只有 1 个元素
db.users.find({ tags: { $size: 1 } }).pretty()

示例里李娜 ["new"]、陈强 ["vip"]、刘洋 ["gamer"],以及第 16 章那条 ["new"] 都是长度 1,会命中。

Warning

$size 不能配合范围运算符(如 $gt)直接用。想查「长度大于 1」,得另建一个记录长度的字段,或用聚合阶段 $expr 配合 $size 表达式。

17.5 $elemMatch:按条件匹配数组元素

当数组里是文档,且要「同一个元素满足多个条件」时,用 $elemMatch

// items 里存在某个元素:product 是键盘 且 qty > 1
db.orders.find({
  items: {
    $elemMatch: { product: "键盘", qty: { $gt: 1 } }
  }
}).pretty()

只有 1003 号订单的键盘 qty: 3 满足,所以命中它。

Note

据 MongoDB 8.3 官方文档,$elemMatch 保证多个条件落在「同一个数组元素」上;若分别写 { "items.product": "键盘", "items.qty": { $gt: 1 } },则可能跨不同元素满足,结果不同。

17.6 $nin:数组不含某些值

$nin 用在数组字段上时,表示「数组里不出现列表中的任何一个值」:

// tags 数组里不含 "vip"
db.users.find({ tags: { $nin: ["vip"] } }).pretty()

这会命中那些 tags 里没有 vip 的用户(如李娜、刘洋,以及第 16 章那条 ["new"] 的用户)。

17.7 小结

数组查询记住四把刷子:

  • 直接写值:数组含该元素即可。
  • $all:必须含全部指定元素。
  • $size:按元素个数匹配。
  • $elemMatch:数组元素是文档时,约束「同一元素」满足多条件。