Mongodb命令大全

目录

数据库命令

集合(表)命令

文档(数据)命令

[_id 字段说明](#_id 字段说明)

插入

[插入单个文档(插入一条数据) insertOne](#插入单个文档(插入一条数据) insertOne)

[插入多个文档(插入多条数据) insertMany](#插入多个文档(插入多条数据) insertMany)

修改

[更新一条文档(修改一条数据) updateOne](#更新一条文档(修改一条数据) updateOne)

[更新多个文档(修改多条数据) updateMany](#更新多个文档(修改多条数据) updateMany)

[替换文档中的所有字段值 replaceOne](#替换文档中的所有字段值 replaceOne)

[重命名字段 $rename](#重命名字段 $rename)

[向文档中添加时间字段,时间为当前时间 $currentDate](#向文档中添加时间字段,时间为当前时间 $currentDate)

[向文档中的数组插入数据 $addToSet](#向文档中的数组插入数据 $addToSet)

[从文档数组中移除数据 $pull](#从文档数组中移除数据 $pull)

删除

[删除一个文档(删除一条数据) deleteOne](#删除一个文档(删除一条数据) deleteOne)

[删除多个文档(删除多条数据) deleteMany](#删除多个文档(删除多条数据) deleteMany)

删除集合,包括集合中的所有文档(删除表)

删除集合中的所有文档,保留集合

[批量操作 bulkWrite](#批量操作 bulkWrite)

查询

[查询单个文档(查询单个数据) findOne](#查询单个文档(查询单个数据) findOne)

[查询多个文档(查询多个数据) find](#查询多个文档(查询多个数据) find)

范围查询

[and 查询](#and 查询)

[or 查询](#or 查询)

[not 查询](#not 查询)

[nor 查询](#nor 查询)

[in 查询](#in 查询)

[nin 查询](#nin 查询)

[正则查询 regex](#正则查询 regex)

内嵌文档查询

数组文档查询

去重

[查询排序 sort](#查询排序 sort)

[分页查询 skip limit](#分页查询 skip limit)

[查询只返回指定列 投影](#查询只返回指定列 投影)

[查询不返回指定的列 投影](#查询不返回指定的列 投影)

[查询统计个数 count](#查询统计个数 count)

聚合查询

[1. 查询用户表中name=tom的文档](#1. 查询用户表中name=tom的文档)

[2. 查询订单表中 amount大于 300 的订单](#2. 查询订单表中 amount大于 300 的订单)

[3. 查询订单中 status = 1 并且 amount 大于 300 的订单](#3. 查询订单中 status = 1 并且 amount 大于 300 的订单)

[4. 内嵌查询](#4. 内嵌查询)

[5. 查找 amount 大于 200 的订单,并按 amount 降序排序](#5. 查找 amount 大于 200 的订单,并按 amount 降序排序)

[分组查询 $group](#分组查询 $group)

[1. 按 item 字段分组并计算总销售量](#1. 按 item 字段分组并计算总销售量)

[2. 按 date 字段分组并计算总销售额](#2. 按 date 字段分组并计算总销售额)

[3. 按 item 分组,并计算每种商品的平均价格和总销售量](#3. 按 item 分组,并计算每种商品的平均价格和总销售量)

[4. 按 item 分组,并创建一个包含所有销售日期的数组](#4. 按 item 分组,并创建一个包含所有销售日期的数组)

[5. 按 item 分组,并创建一个包含唯一销售日期的数组](#5. 按 item 分组,并创建一个包含唯一销售日期的数组)

[计划查询 $project](#计划查询 $project)

[1. 查询结果只返回指定字段 投影](#1. 查询结果只返回指定字段 投影)

[2. 查询结果不返回指定字段 投影](#2. 查询结果不返回指定字段 投影)

[3. 重命名字段](#3. 重命名字段)

[4. 计算新字段](#4. 计算新字段)

[5. 只显示指定的嵌套字段](#5. 只显示指定的嵌套字段)

[内联查询 $lookup](#内联查询 $lookup)

[1. 两张集合,关联查询](#1. 两张集合,关联查询)

[2. 三张集合,关联查询](#2. 三张集合,关联查询)

[外联查询 $unwind](#外联查询 $unwind)


数据库命令

  • 选择数据库

    // 语法
    use <database_name>

    // 示例
    use test

  • 显示当前所在库

    db

  • 显示数据库列表

    show dbs

  • 删除当前所在数据库

    db.dropDatabase()

  • 创建数据库

    在插入数据时自动创建


集合(表)命令

  • 显示集合列表

    show collections

  • 创建集合

    // 语法
    db.createCollection(<collection_name>, { options })

    // 示例
    db.createCollection("products")

    // 创建固定大小的集合,当集合达到指定的大小时,它会覆盖最早的文档。固定大小的集合的文档一旦插入就不允许修改

    // 示例,创建固定大小的集合,capped=true表示集合有大小上限,size是字节单位
    db.createCollection("products", {capped: true, size: 1048576 })

    // 示例,创建固定大小的集合,capped=true表示集合有大小上限,size是字节单位,max是最大文档数
    db.createCollection("products", {capped: true, size: 1048576, max: 1000})

  • 删除集合

    // 语法
    db.<collection_name>.drop()

    // 示例
    db.products.drop()


文档(数据)命令

_id 字段说明

_id 字段是每个文档的唯一标识符,确保每个文档在集合中是唯一的。这个字段在每个文档中都是必须的,并且在插入文档时会自动生成。如果没有显式指定 _id,MongoDB 会为其生成一个唯一的 ObjectId。

假如我们在插入数据时没有指定_id值

bash 复制代码
db.users.insertOne({ "name": "Alice", "age": 25 })

MongoDB 会自动生成一个 ObjectId 作为 _id,如下:

bash 复制代码
{
  "_id": ObjectId("60a7c0c8b59b3c001c8e4f2d"),
  "name": "Alice",
  "age": 25
}

使用 _id 进行查询

bash 复制代码
db.users.find({ "_id": ObjectId("60a7c0c8b59b3c001c8e4f2d") })

指定_id值

bash 复制代码
db.users.insertOne({ "_id": 1, "name": "Bob", "age": 30 })
bash 复制代码
{
  "_id": 1,
  "name": "Bob",
  "age": 30
}

使用 _id 进行查询

bash 复制代码
db.users.find({ "_id": 1 })

插入

插入单个文档(插入一条数据) insertOne
bash 复制代码
// 语法
db.<collection_name>.insertOne({})
bash 复制代码
// 示例
db.users.insertOne({
  name: "Tom",
  age: 30,
  email: "tom@example.com"
})
插入多个文档(插入多条数据) insertMany
bash 复制代码
// 语法
db.<collection_name>.insertMany([
  {}, {}
])
bash 复制代码
// 示例
db.orders.insertMany([
  { item: "book", qty: 10, price: 15 },
  { item: "pen", qty: 20, price: 1.5 }
])

修改

更新一条文档(修改一条数据) updateOne
  1. 更新 name 为 "Alice" 的文档的 age 字段
bash 复制代码
db.users.updateOne(
  { name: "Alice" },
  { $set: { age: 26 } }
)
  1. 如果没有找到文档,则插入一个新文档 upsert: true
bash 复制代码
db.users.updateOne(
  { name: "Charlie" },
  { $set: { age: 35 }, $setOnInsert: { createdAt: new Date() } },
  { upsert: true }
)

更新多个文档(修改多条数据) updateMany
  1. 将所有 age 小于 30 的用户的 status 更新为 "young"
bash 复制代码
db.users.updateMany(
  { age: { $lt: 30 } },
  { $set: { status: "young" } }
)
  1. 如果没有找到文档,则插入一个新文档 upsert: true
bash 复制代码
db.users.updateMany(
  { status: "inactive" },
  { $set: { status: "active" } },
  { upsert: true }
)

替换文档中的所有字段值 replaceOne
  1. 用新文档替换 name 为 "Alice" 的文档
bash 复制代码
db.users.replaceOne(
  { name: "Alice" },
  { name: "Alice", age: 27, status: "active" }
)
  1. 如果没有找到文档,则插入一个新文档 upsert: true
bash 复制代码
db.users.replaceOne(
  { name: "David" },
  { name: "David", age: 40, status: "new" },
  { upsert: true }
)

重命名字段 $rename
bash 复制代码
db.users.updateOne(
  { name: "Alice" },
  { $rename: { "address.city": "address.town" } }
)

向文档中添加时间字段,时间为当前时间 $currentDate
bash 复制代码
db.users.updateOne(
  { name: "Alice" },
  { $currentDate: { create_time: true } }
)

向文档中的数组插入数据 $addToSet
db.users.updateOne(
  { name: "Tom" },
  { $addToSet: { address: "Shenzhen" } }
)

从文档数组中移除数据 $pull
db.users.updateOne(
  { name: "Tom" },
  { $pull: { address: "Shenzhen" } }
)

删除

删除一个文档(删除一条数据) deleteOne
bash 复制代码
db.users.deleteOne({ name: "Tom" })
删除多个文档(删除多条数据) deleteMany
bash 复制代码
// 删除所有 age 小于 30 的文档
db.users.deleteMany({ age: { $lt: 30 } })
删除集合,包括集合中的所有文档(删除表)
bash 复制代码
// 语法
db.<collection_name>.drop()
bash 复制代码
// 示例
db.users.drop()
删除集合中的所有文档,保留集合
bash 复制代码
db.users.deleteMany({})

批量操作 bulkWrite

bulkWrite() 方法允许执行多种插入、更新和删除操作的批量操作。它适用于需要一次性处理多个写操作的场景。

  • 执行多种操作(插入、更新、删除)
bash 复制代码
db.users.bulkWrite([
  { insertOne: { document: { name: "Grace", age: 29, email: "grace@example.com" } } },
  { updateOne: { filter: { name: "Bob" }, update: { $set: { age: 31 } } } },
  { deleteOne: { filter: { name: "Charlie" } } }
])
  • 设置 ordered 选项为 false,使得即使遇到错误也会继续执行其他操作
bash 复制代码
db.users.bulkWrite([
  { insertOne: { document: { name: "Hank", age: 45, email: "hank@example.com" } } },
  { updateOne: { filter: { name: "David" }, update: { $set: { status: "active" } } } }
], { ordered: false })

查询

符号 说明
$eq 等于
$ne 不等于
$gt 大于
$lt 小于
$gte 大于等于
$lte 小于等于
[查询操作符]

| 符号 | 说明 |

$and 逻辑与
$or 逻辑或
$not 逻辑非
$nor 逻辑非或
[逻辑操作符]
查询单个文档(查询单个数据) findOne
bash 复制代码
// 语法
db.<collection_name>.findOne({ 列名: "值" });
bash 复制代码
// 示例,对比mysql:select * from users where name = 'Tom'
db.users.findOne({ name: "Tom" });
查询多个文档(查询多个数据) find
bash 复制代码
// 示例,对比mysql:select * from users where age > 25
db.users.find({ age: { $gt: 25 } });
bash 复制代码
// 将返回结果游标转成数组
db.users.find({ age: { $gt: 25 } }).toArray();
范围查询
bash 复制代码
// 查找年龄在 18 到 30 岁之间的用户
db.users.find({ age: { $gte: 18, $lte: 30 } });
and 查询
bash 复制代码
// 查找年龄大于 25 岁且性别为 "男" 的用户
db.users.find({ $and: [{ age: { $gt: 25 } }, { gender: "男" }] });
or 查询
bash 复制代码
// 查找年龄小于 18 岁或大于 60 岁的用户
db.users.find({ $or: [{ age: { $lt: 18 } }, { age: { $gt: 60 } }] });
not 查询
bash 复制代码
// 查询 age 不等于 25 的文档
db.users.find({
    age: { $not: { $eq: 25 } }
});


// 等价于
db.users.find({
    age: { $ne: 25 }
});
nor 查询

nor可以理解为多个not条件的组合

bash 复制代码
// 查询年龄不是 25 且地址不是Shenzhen的文档
db.users.find({
    $nor: [
        { age: 25 },
        { address: "Shenzhen" }
    ]
});


// 查询年龄不是 25 或 30 的用户, 且地址不是Shenzhen的文档
db.users.find({
    $nor: [
        { age: 25 },
        { age: 30},
        { address: "Shenzhen" }
    ]
});
in 查询
bash 复制代码
// 查询年龄是 25 和 35 的文档
db.users.find({ age: { $in: [25, 35] } });
nin 查询
bash 复制代码
// 查询年龄不是是 25 和 35 的文档
db.users.find({ age: { $nin: [25, 35] } });
正则查询 regex
bash 复制代码
// 查询 name 中包含 Tom 的文档
db.users.find({
    name: { $regex: "Tom" }
});


// i 忽略大小写
db.users.find({
    name: { $regex: "tom", $options: "i" }
});
bash 复制代码
// 匹配电子邮件以 "dave" 开头的用户
db.users.find({
    email: { $regex: "^dave" }
});

// 匹配电子邮件以 "domain.com" 结尾的用户
db.users.find({
    email: { $regex: "domain\\.com$" }
});

// 多行模式,匹配电子邮件包含 "example" 或 "domain" 的用户
db.users.find({
    email: { $regex: "example|domain" }
});
内嵌文档查询
bash 复制代码
// 数据结构
[
  {
    "_id": 1,
    "name": "Alice",
    "age": 30,
    "address": {
      "street": "123 Elm St",
      "city": "New York",
      "state": "NY",
      "zip": "10001"
    }
  },
  {
    "_id": 2,
    "name": "Bob",
    "age": 25,
    "address": {
      "street": "456 Oak St",
      "city": "Los Angeles",
      "state": "CA",
      "zip": "90001"
    }
  }
]
bash 复制代码
// 查询语句,查找有地址的用户,并且地址的城市是 "New York"
db.users.find({ "address.city": "New York" });
数组文档查询

$elemMatch:匹配数组中满足条件的元素

bash 复制代码
// 数据结构
[
  {
    "_id": 1,
    "name": "Alice",
    "age": 30,
    "friends": [
      { "name": "Bob", "age": 25 },
      { "name": "Charlie", "age": 32 }
    ]
  },
  {
    "_id": 2,
    "name": "David",
    "age": 28,
    "friends": [
      { "name": "Eve", "age": 22 },
      { "name": "Frank", "age": 29 }
    ]
  }
]
bash 复制代码
// 查询语句,查找friends中包含年龄大于 30 岁的用户
db.users.find({ "friends": { $elemMatch: { age: { $gt: 30 } } } })
去重
bash 复制代码
// 给 age 字段去重
db.users.distinct("age");

// age 大于 25 的用户的去重 name 字段
db.users.distinct("name", { age: { $gt: 25 } });
查询排序 sort
bash 复制代码
// 使用关键字sort,按照 age 升序排序
db.users.find().sort({ age: 1 });
bash 复制代码
// 按照 age 降序排序
db.users.find().sort({ age: -1 });
分页查询 skip limit
bash 复制代码
// 使用 limit 关键字,返回前5条数据
db.users.find().limit(5);
bash 复制代码
// 分页查询,跳过前 5 个文档,并返回接下来的 5 个文档
db.users.find().skip(5).limit(5)
查询只返回指定列 投影
bash 复制代码
// 返回 name age,不返回_id, 0表示不返回,1表示返回
db.users.find({}, { name: 1, age: 1, _id: 0 });
查询不返回指定的列 投影
bash 复制代码
// 不返回 name, 其他字段都返回,0表示不返回,1表示返回
db.users.find({}, { name: 0 });
查询统计个数 count
bash 复制代码
// 查询集合中的所有文档数量
db.users.count();

// 查询年龄大于 30 的文档的个数
db.users.count({ age: { $gt: 10 } });
db.users.find({ age: { $gt: 10 } }).count()
bash 复制代码
// 这里要使用聚合aggregate,$match的意思和find一样
db.<collection_name>.aggregate([
  { $match: { name: "Tom" } },
  { $count: "total" }
])
聚合查询
符号 说明
$sum 计算和
$avg 计算平均值
$min 计算最小值
$max 计算最大值
$first 取每组中的第一个文档
$last 取每组中的最后一个文档
$push 将每组中的某个值添加到数组中
$addToSet 将每组中的唯一值添加到数组中(去重)
$count 计算文档数量
[聚合操作符]
符号 说明
$add 两个数、日期、时间相加
$subtract 两个数、日期、时间相减
$multiply 两个数相乘
$divide 两个数相除
$mod 两个数取余
$abs 数字的绝对值
$ceil 数字向上取整
$floor 数字向下取整
$exp 返回 e(自然对数的底数)取指定数字次方的值
$ln 数字的自然对数
$log 数字以指定底数为底的对数
$log10 数字以10为底的对数
$pow 指定数字的指定次方的值
$sqrt 数字的平方根
$trunc 数字截断为整数的值(删除小数部分)
[算数操作符]

$match

$match 是 MongoDB 聚合管道中的一个重要阶段,用于筛选文档,仅输出符合指定条件的文档。它的作用类似于 find 操作,但它是聚合管道的一部分,通常用于数据预处理和过滤,以便后续阶段能够处理更少、更相关的数据。

语法:

bash 复制代码
db.<collection_name>.aggregate([
  { $match: { <query> } }
])

// <query>:标准的查询条件,类似于 find 方法中的查询条件。
1. 查询用户表中name=tom的文档
bash 复制代码
db.users.aggregate([
  { $match: { name: "Tom" } }
])
2. 查询订单表中 amount大于 300 的订单
bash 复制代码
db.orders.aggregate([
  { $match: { amount: { $gt: 300 } } }
])
3. 查询订单中 status = 1 并且 amount 大于 300 的订单
bash 复制代码
db.orders.aggregate([
  { $match: { $and: [ { status: "A" }, { amount: { $gt: 300 } } ] } }
])
4. 内嵌查询
bash 复制代码
db.orders.aggregate([
  { $match: { "address.city": "New York" } }
])
5. 查找 amount 大于 200 的订单,并按 amount 降序排序
bash 复制代码
db.orders.aggregate([
  { $match: { amount: { $gt: 200 } } },
  { $sort: { amount: -1 } }
])

分组查询 $group

sales集合数据如下

bash 复制代码
[
  { "_id": 1, "item": "apple", "price": 10, "quantity": 2, "date": "2023-01-01" },
  { "_id": 2, "item": "banana", "price": 5, "quantity": 10, "date": "2023-01-01" },
  { "_id": 3, "item": "apple", "price": 10, "quantity": 5, "date": "2023-01-02" },
  { "_id": 4, "item": "banana", "price": 5, "quantity": 7, "date": "2023-01-02" },
  { "_id": 5, "item": "orange", "price": 8, "quantity": 8, "date": "2023-01-03" }
]

1. 按 item 字段分组并计算总销售量
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      totalQuantity: { $sum: "$quantity" }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "apple", "totalQuantity": 7 },
  { "_id": "banana", "totalQuantity": 17 },
  { "_id": "orange", "totalQuantity": 8 }
]

2. 按 date 字段分组并计算总销售额
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$date",
      totalSales: { $sum: { $multiply: ["$price", "$quantity"] } }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "2023-01-01", "totalSales": 70 },
  { "_id": "2023-01-02", "totalSales": 85 },
  { "_id": "2023-01-03", "totalSales": 64 }
]
3. 按 item 分组,并计算每种商品的平均价格和总销售量
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      avgPrice: { $avg: "$price" },
      totalQuantity: { $sum: "$quantity" }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "apple", "avgPrice": 10, "totalQuantity": 7 },
  { "_id": "banana", "avgPrice": 5, "totalQuantity": 17 },
  { "_id": "orange", "avgPrice": 8, "totalQuantity": 8 }
]
4. 按 item 分组,并创建一个包含所有销售日期的数组
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      dates: { $push: "$date" }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "apple", "dates": ["2023-01-01", "2023-01-02"] },
  { "_id": "banana", "dates": ["2023-01-01", "2023-01-02"] },
  { "_id": "orange", "dates": ["2023-01-03"] }
]
5. 按 item 分组,并创建一个包含唯一销售日期的数组
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      uniqueDates: { $addToSet: "$date" }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "apple", "uniqueDates": ["2023-01-01", "2023-01-02"] },
  { "_id": "banana", "uniqueDates": ["2023-01-01", "2023-01-02"] },
  { "_id": "orange", "uniqueDates": ["2023-01-03"] }
]
  1. 查询结果后再分组
bash 复制代码
db.sales.aggregate([
  { $match: { item: "apple" } },
  {
    $group: {
      _id: "$date",
      totalQuantity: { $sum: "$quantity" },
      avgPrice: { $avg: "$price" }
    }
  }
])

结果

bash 复制代码
[
  { "_id": "2023-01-01", "totalQuantity": 2, "avgPrice": 10 },
  { "_id": "2023-01-02", "totalQuantity": 5, "avgPrice": 10 }
]
  1. 对分组结果进行排序
bash 复制代码
db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      totalQuantity: { $sum: "$quantity" }
    }
  },
  { $sort: { totalQuantity: -1 } }
])

结果

bash 复制代码
[
  { "_id": "banana", "totalQuantity": 17 },
  { "_id": "apple", "totalQuantity": 7 },
  { "_id": "orange", "totalQuantity": 8 }
]

计划查询 $project

有users集合数据如下

bash 复制代码
[
  { "_id": 1, "name": "Alice", "age": 25, "address": { "city": "New York", "state": "NY" }, "score": 80 },
  { "_id": 2, "name": "Bob", "age": 30, "address": { "city": "Los Angeles", "state": "CA" }, "score": 90 }
]
1. 查询结果只返回指定字段 投影
bash 复制代码
db.users.aggregate([
  {
    $project: {
      name: 1,
      age: 1
    }
  }
])

结果

bash 复制代码
[
  { "_id": 1, "name": "Alice", "age": 25 },
  { "_id": 2, "name": "Bob", "age": 30 }
]
2. 查询结果不返回指定字段 投影
bash 复制代码
db.users.aggregate([
  {
    $project: {
      address: 0
    }
  }
])

结果

bash 复制代码
[
  { "_id": 1, "name": "Alice", "age": 25, "score": 80 },
  { "_id": 2, "name": "Bob", "age": 30, "score": 90 }
]
3. 重命名字段
bash 复制代码
db.users.aggregate([
  {
    $project: {
      username: "$name",
      age: 1
    }
  }
])

结果

bash 复制代码
[
  { "_id": 1, "username": "Alice", "age": 25 },
  { "_id": 2, "username": "Bob", "age": 30 }
]
4. 计算新字段

计算新的字段 discountedScore,其值为 score 的 90%:

bash 复制代码
db.users.aggregate([
  {
    $project: {
      name: 1,
      age: 1,
      discountedScore: { $multiply: ["$score", 0.9] }
    }
  }
])

结果

bash 复制代码
[
  { "_id": 1, "name": "Alice", "age": 25, "discountedScore": 72 },
  { "_id": 2, "name": "Bob", "age": 30, "discountedScore": 81 }
]
5. 只显示指定的嵌套字段
bash 复制代码
db.users.aggregate([
  {
    $project: {
      name: 1,
      age: 1,
      "address.city": 1
    }
  }
])

结果

bash 复制代码
[
  { "_id": 1, "name": "Alice", "age": 25, "address": { "city": "New York" } },
  { "_id": 2, "name": "Bob", "age": 30, "address": { "city": "Los Angeles" } }
]

内联查询 $lookup

lookup 是 MongoDB 的一个聚合管道操作符,用于执行左外连接(left outer join)。它允许你将来自不同集合的数据合并到一个文档中。lookup 操作符将当前集合中的每个文档与另一个集合中的文档进行匹配,并将匹配的结果添加到当前文档中。(类似于 SQL 的 left join)

1. 两张集合,关联查询

有两个集合 orders 订单表和 products 产品表,orders 集合中的文档中的 productId 字段,指向 products 集合中 _id 字段,数据内容如下:

bash 复制代码
// orders 集合
{ "_id": 1, "productId": 101, "quantity": 2 }
{ "_id": 2, "productId": 102, "quantity": 1 }

// products 集合
{ "_id": 101, "name": "Widget", "price": 19.99 }
{ "_id": 102, "name": "Gadget", "price": 29.99 }

内联查询语句

bash 复制代码
db.orders.aggregate([
    {
        $lookup: {
            from: "products",
            localField: "productId",
            foreignField: "_id",
            as: "productDetails"
        }
    }
])

参数说明:

db.orders.aggregate([...]):aggregate 方法在 orders 集合上运行。这意味着整个聚合管道操作是针对 orders 集合的。

from:指定要连接的目标集合的名称。示例中我们是从 products 集合中查询关联数据。

**localField:**指定当前集合(orders源集合)中用于连接的字段名称。示例中和products关联的是productId字段。

foreignField :指定目标集合(from 集合)中用于连接的字段名称,示例中和orders关联的是_id字段。

as:查询结果的别名,指定输出数组字段的名称。

2. 三张集合,关联查询

orders 订单表和 products 表关联,products 表和 categories 关联,数据内容如下:

bash 复制代码
// orders  订单表
{ "_id": 1, "productId": 101, "quantity": 2 }
{ "_id": 2, "productId": 102, "quantity": 1 }

// products 产品表
{ "_id": 101, "categoryId": 201, "name": "Widget" }
{ "_id": 102, "categoryId": 202, "name": "Gadget" }

// categories 产品类别表
{ "_id": 201, "name": "Electronics" }
{ "_id": 202, "name": "Home Goods" }

内联查询语句

bash 复制代码
db.orders.aggregate([
    {
        $lookup: {
            from: "products",
            localField: "productId",
            foreignField: "_id",
            as: "productDetails"
        }
    },
    {
        $lookup: {
            from: "categories",
            localField: "productDetails.categoryId",
            foreignField: "_id",
            as: "productDetails.categoryDetails"
        }
    }
])

外联查询 $unwind

$unwind 是 MongoDB 聚合管道中的另一个操作符,用于将数组字段展开成多个文档。如果在使用 $lookup 时,目标集合的字段是一个数组(如上面的例子中 productDetails 是一个数组),使用 $unwind 可以将每个数组元素展开为独立的文档。

示例一:配置 $lookup 使用

bash 复制代码
db.orders.aggregate([
    {
        $lookup: {
            from: "products",
            localField: "productId",
            foreignField: "_id",
            as: "productDetails"
        }
    },
    {
        $unwind: "$productDetails"
    }
])

示例二:展开数组

有如下基础数据:

bash 复制代码
db.users.insertMany([
  { _id: 1, name: "Alice", address: ["广州", "北京", "杭州"] },
  { _id: 2, name: "Bob", address: ["上海", "武汉"] },
  { _id: 3, name: "Charlie", address: [] }
])

外联查询语句

bash 复制代码
db.users.aggregate([
    { $unwind: "$address" }
])

查询结果

bash 复制代码
[
  { "_id": 1, "name": "Alice", "address": "广州" },
  { "_id": 1, "name": "Alice", "address": "北京" },
  { "_id": 1, "name": "Alice", "address": "杭州" },
  { "_id": 2, "name": "Bob", "address": "上海" },
  { "_id": 2, "name": "Bob", "address": "武汉" }
]
相关推荐
月光水岸New1 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6751 小时前
数据库基础1
数据库
我爱松子鱼1 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo2 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser3 小时前
【SQL】多表查询案例
数据库·sql
Galeoto3 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)3 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231113 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
喝醉酒的小白3 小时前
PostgreSQL:更新字段慢
数据库·postgresql
敲敲敲-敲代码3 小时前
【SQL实验】触发器
数据库·笔记·sql