《MongoDB 常用命令详解:从数据库操作到高级查询》

发布于:2025-08-30 ⋅ 阅读:(28) ⋅ 点赞:(0)

前言:案例背景

本文以“文章评论存储”为实战场景,基于以下数据模型展开命令讲解:

  • 数据库articledb(存储文章相关数据)
  • 集合comment(存储文章评论,类似关系型数据库的“表”)
  • 字段结构
字段名 类型 含义 备注
_id ObjectId/String 主键 MongoDB 自动生成或手动指定,确保唯一性
articleid String 文章 ID 关联对应的文章
content String 评论内容 核心业务字段
userid String 评论人 ID 关联用户表
nickname String 评论人昵称 冗余存储,减少关联查询
createdatetime Date 评论时间 支持时间范围查询
likenum Int32 点赞数 需用 NumberInt() 声明整型
replynum Int32 回复数 同上
state String 状态 1:可见;0:不可见
parentid String 上级 ID 0 表示顶级评论,非 0 表示回复评论

一、数据库操作

MongoDB 的数据库操作包括“选择/创建”“查看”“删除”,核心是通过 use 命令切换上下文。

1.1 选择与创建数据库

语法use 数据库名称

  • 若数据库不存在,执行 use 后插入数据会自动创建;
  • 若数据库已存在,直接切换到该数据库。

示例:创建并切换到 articledb 数据库

use articledb

1.2 查看数据库

语法

  • 查看所有有权限的数据库:show dbsshow databases
  • 查看当前正在使用的数据库:db

注意:刚创建的数据库不会显示在 show dbs 结果中,需插入数据(创建集合并写入文档)后才会持久化显示。

示例

// 查看所有数据库
show dbs
// 查看当前数据库
db  // 输出:articledb

1.3 删除数据库

语法db.dropDatabase()

  • 仅删除当前正在使用的数据库;
  • 需谨慎操作,删除后数据不可恢复。

示例:删除 articledb 数据库

use articledb  // 先切换到目标数据库
db.dropDatabase()  // 返回 { "dropped" : "articledb", "ok" : 1 } 表示成功

1.4 数据库命名规范

  • 不能是空字符串或包含空格、.$/\\0(空字符);
  • 需全部小写,最多 64 字节;
  • 保留数据库(不可随意操作):
    • admin:权限根数据库,用户在此数据库添加后继承所有权限;
    • local:本地数据库,数据不复制,仅存储单节点私有数据;
    • config:分片集群专用,存储分片配置信息。

二、集合操作

集合(Collection)类似关系型数据库的“表”,支持显式创建隐式创建(推荐)。

2.1 显式创建集合(了解)

语法db.createCollection("集合名称")

  • 适用于需提前配置集合属性(如分片、索引)的场景,常规开发很少用。

示例:创建 comment 集合

use articledb
db.createCollection("comment")

2.2 查看集合

语法show collectionsshow tables

示例:查看 articledb 中的所有集合

use articledb
show collections  // 输出:comment(若已创建)

2.3 隐式创建集合(推荐)

MongoDB 允许直接向不存在的集合插入文档,集合会自动创建,无需手动声明。
示例:向不存在的 comment 集合插入文档,自动创建集合

use articledb
// 插入文档时,若 comment 不存在则自动创建
db.comment.insert({"articleid":"100000","content":"今天天气真好"})

2.4 删除集合

语法db.集合名称.drop()

  • 删除后集合及所有文档永久删除,不可恢复。

示例:删除 comment 集合

use articledb
db.comment.drop()  // 返回 true 表示成功,false 表示集合不存在

2.5 集合命名规范

  • 不能是空字符串或包含 \0(空字符);
  • 不能以 system. 开头(系统集合保留前缀);
  • 不能包含 $(系统集合专用,用户集合避免使用)。

三、文档基本 CRUD 操作

文档(Document)是 MongoDB 的最小存储单位(类似关系型数据库的“行”),格式为 BSON(二进制 JSON)。

3.1 文档插入(Create)

支持单个文档插入批量文档插入,核心命令为 insert()insertMany()

3.1.1 单个文档插入

语法

db.collection.insert(
  <document>,  // 单个文档(BSON 格式)
  {
    writeConcern: <document>,  // 可选,写入确认机制
    ordered: <boolean>         // 可选,仅数组插入有效,默认 true(有序插入)
  }
)

示例:向 comment 集合插入一条评论

use articledb
db.comment.insert({
  "articleid": "100000",
  "content": "今天天气真好,阳光明媚",
  "userid": "1001",
  "nickname": "Rose",
  "createdatetime": new Date(),  // 插入当前时间
  "likenum": NumberInt(10),     // 整型需用 NumberInt() 声明
  "state": null                 // 空值用 null
})
// 成功返回:WriteResult({ "nInserted" : 1 })

关键提示

  1. 未指定 _id 时,MongoDB 自动生成 ObjectId 作为主键;
  2. 数字默认是 double 类型,存储整型需用 NumberInt(整数)NumberLong(长整数)
  3. 日期用 new Date() 生成(UTC 时间,可通过工具转换为本地时间)。
3.1.2 批量文档插入

语法

db.collection.insertMany(
  [ <document1>, <document2>, ... ],  // 文档数组
  {
    writeConcern: <document>,  // 可选,写入确认机制
    ordered: <boolean>         // 可选,默认 true(有序插入,失败则终止)
  }
)

示例:批量插入 5 条评论(手动指定 _id

use articledb
db.comment.insertMany([
  {
    "_id": "1",  // 手动指定主键(String 类型)
    "articleid": "100001",
    "content": "我们不应该把清晨浪费在手机上,健康很重要",
    "userid": "1002",
    "nickname": "相忘于江湖",
    "createdatetime": new Date("2019-08-05T22:08:15.522Z"),
    "likenum": NumberInt(1000),
    "state": "1"
  },
  {
    "_id": "2",
    "articleid": "100001",
    "content": "我夏天空腹喝凉开水,冬天喝温开水",
    "userid": "1005",
    "nickname": "伊人憔悴",
    "createdatetime": new Date("2019-08-05T23:58:51.485Z"),
    "likenum": NumberInt(888),
    "state": "1"
  },
  { "_id": "3", "articleid": "100001", "content": "我一直喝凉开水", "userid": "1004", "nickname": "杰克船长", "createdatetime": new Date("2019-08-06T01:05:06.321Z"), "likenum": NumberInt(666), "state": "1" },
  { "_id": "4", "articleid": "100001", "content": "专家说不能空腹吃饭", "userid": "1003", "nickname": "凯撒", "createdatetime": new Date("2019-08-06T08:18:35.288Z"), "likenum": NumberInt(2000), "state": "1" },
  { "_id": "5", "articleid": "100001", "content": "刚烧开的水千万不能喝,因为烫嘴", "userid": "1003", "nickname": "凯撒", "createdatetime": new Date("2019-08-06T11:01:02.521Z"), "likenum": NumberInt(3000), "state": "1" }
])

异常处理:批量插入若某条失败,ordered: true 会终止后续插入,可通过 try-catch 捕捉异常:

try {
  db.comment.insertMany([/* 文档数组 */]);
} catch (e) {
  print(e);  // 打印错误信息,已插入成功的文档不会回滚
}

3.2 文档查询(Read)

核心命令为 find()findOne(),支持全量查询条件查询投影查询(指定返回字段)。

3.2.1 全量查询

语法db.collection.find()db.collection.find({})

  • 返回集合中所有文档,默认显示 _id 字段。

示例:查询 comment 集合所有评论

use articledb
db.comment.find()
3.2.2 条件查询

语法db.collection.find({查询条件})

  • 查询条件为 BSON 格式,键为字段名,值为匹配条件。

常见场景

  1. 等值查询:查询 userid = "1003" 的评论
    db.comment.find({userid: "1003"})
    
  2. 查询第一条匹配结果:用 findOne(),返回单个文档(无需遍历)
    db.comment.findOne({userid: "1003"})
    
3.2.3 投影查询(指定返回字段)

语法db.collection.find({查询条件}, {字段名: 1 或 0})

  • 1:显示该字段;0:隐藏该字段;
  • 默认显示 _id,若需隐藏需显式指定 _id: 0

示例

  1. 查询 userid = "1003" 的评论,仅显示 useridnickname 和默认的 _id
    db.comment.find({userid: "1003"}, {userid: 1, nickname: 1})
    
  2. 隐藏 _id,仅显示 useridnickname
    db.comment.find({userid: "1003"}, {userid: 1, nickname: 1, _id: 0})
    

3.3 文档更新(Update)

核心命令为 update(),支持局部更新批量更新字段自增,需注意避免“覆盖更新”。

3.3.1 核心语法
db.collection.update(
  <query>,        // 查询条件(匹配要更新的文档)
  <update>,       // 更新内容(需用更新运算符,如 $set)
  {
    upsert: <boolean>,    // 可选,无匹配时是否创建新文档,默认 false
    multi: <boolean>,     // 可选,是否更新所有匹配文档,默认 false(仅更新第一条)
    writeConcern: <document>  // 可选,写入确认机制
  }
)
3.3.2 常见更新场景
  1. 覆盖更新(不推荐):直接替换整个文档(丢失未指定字段)

    // 错误示例:更新 _id="1" 的文档,仅保留 likenum 字段,其他字段丢失
    db.comment.update({_id: "1"}, {likenum: NumberInt(1001)})
    
  2. 局部更新(推荐):用 $set 运算符仅更新指定字段

    // 正确示例:更新 _id="2" 的文档,仅修改 likenum 为 889
    db.comment.update({_id: "2"}, {$set: {likenum: NumberInt(889)}})
    
  3. 批量更新:设置 multi: true,更新所有匹配文档

    // 更新所有 userid="1003" 的文档,将 nickname 改为“凯撒大帝”
    db.comment.update(
      {userid: "1003"}, 
      {$set: {nickname: "凯撒大帝"}}, 
      {multi: true}
    )
    
  4. 字段自增/自减:用 $inc 运算符实现数值字段的增减

    // 对 _id="3" 的文档,likenum 自增 1(每次执行点赞数+1)
    db.comment.update({_id: "3"}, {$inc: {likenum: NumberInt(1)}})
    // 自减示例:likenum 减 2
    db.comment.update({_id: "3"}, {$inc: {likenum: NumberInt(-2)}})
    

3.4 文档删除(Delete)

核心命令为 remove(),支持条件删除全量删除,需谨慎操作。

3.4.1 核心语法
db.collection.remove(<query>)  // query:删除条件,空对象 {} 表示删除所有
3.4.2 常见场景
  1. 条件删除:删除指定条件的文档

    // 删除 _id="1" 的文档
    db.comment.remove({_id: "1"})
    
  2. 全量删除(谨慎):删除集合中所有文档(集合结构保留)

    // 危险!删除 comment 集合所有文档
    db.comment.remove({})
    

注意remove() 仅删除文档,不删除集合结构;若需删除集合及结构,用 db.collection.drop()

四、文档高级查询

包括统计查询分页查询排序查询模糊查询比较查询等,满足复杂业务场景。

4.1 统计查询

count() 方法统计匹配文档的数量,支持条件统计。

语法db.collection.count(<query>)

  • query:可选,统计符合条件的文档数;空则统计所有。

示例

  1. 统计 comment 集合所有文档数
    db.comment.count()
    
  2. 统计 userid="1003" 的文档数
    db.comment.count({userid: "1003"})
    

4.2 分页查询

结合 skip()(跳过指定数量文档)和 limit()(返回指定数量文档)实现分页。

语法db.collection.find().skip(跳过数).limit(每页条数)

  • 分页公式:skip((页码-1)*每页条数).limit(每页条数)

示例:每页显示 2 条评论,查询第 1-3 页

// 第 1 页:跳过 0 条,显示 2 条
db.comment.find().skip(0).limit(2)
// 第 2 页:跳过 2 条,显示 2 条
db.comment.find().skip(2).limit(2)
// 第 3 页:跳过 4 条,显示 2 条
db.comment.find().skip(4).limit(2)

4.3 排序查询

sort() 方法对查询结果排序,支持单字段和多字段排序。

语法db.collection.find().sort({字段名: 1 或 -1})

  • 1:升序;
  • -1:降序;

网站公告

今日签到

点亮在社区的每一天
去签到