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": "武汉" }
]
相关推荐
鹿子铭27 分钟前
单线程Redis:Redis为什么这么快
数据库·redis
JSON_L1 小时前
MySQL 事务处理
数据库·mysql
爱打lan球的程序员3 小时前
redis分布式锁和lua脚本
数据库·redis·分布式
说书客啊3 小时前
计算机毕业设计 | springboot旅行旅游网站管理系统(附源码)
java·数据库·spring boot·后端·毕业设计·课程设计·旅游
hummhumm3 小时前
数据库系统 第46节 数据库版本控制
java·javascript·数据库·python·sql·json·database
ac-er88883 小时前
Flask如何创建并运行数据库迁移
数据库·python·flask
传而习乎4 小时前
【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响
数据库·postgresql
King.6244 小时前
SQLynx如何提高企业数据库安全?
数据库·sql·mysql·postgresql·oracle
夜夜亮晶晶5 小时前
MySQL——表操作
数据库·mysql
GGBondlctrl6 小时前
【MySQL】初识MySQL—MySQL是啥,以及如何简单操作???
数据库·mysql