ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MongoDB入门实战:从安装到增删改查,一文掌握文档数据库核心用法

MongoDB入门实战:从安装到增删改查,一文掌握文档数据库核心用法 MongoDB 这个名字这两年只要碰过后端开发或者数据存储基本都会撞见。我第一次接触还是在某个实训平台上做“初识MongoDB”的练习当时只给了几个操作题和一个连接串我照着敲了几条命令感觉跟 MySQL 完全不一样——没有表结构、没有行和列数据像 JSON 一样一层套一层那股别扭劲过了好几天才缓过来。但等你真正上手跑通一轮增删改查之后你会发现这种“无模式文档”的设计反而是日常开发里最接近业务直觉的一种存储方式。这篇文章我就以“初识 MongoDB”为主线把从下载安装、核心概念到最常用的增删改查操作完整捋一遍。内容面向的是完全没接触过 MongoDB 的初学者以及用过但一直没搞懂“为什么这么设计”的开发者。你在 Windows 上装过但报错了或者装了之后不知道怎么开始操作这篇文章都能帮你解决。咱们直接进入正题。1. 先搞清楚 MongoDB 到底在解决什么问题很多初学者容易陷入一个误区把 MongoDB 当成 MySQL 的替代品然后用关系型数据库的思路去套它结果越学越糊涂。实际上MongoDB 属于 NoSQL 里的文档数据库它解决的核心问题是让“存储结构”能跟着“业务逻辑”走而不是反过来。1.1 为什么会出现“文档数据库”这种东西传统关系型数据库在存储数据之前必须先设计表结构、定义字段、确定字段类型还要考虑表与表之间的外键关系。一旦业务需求变了比如给用户表增加一个“个人标签”字段就得执行 ALTER TABLE数据量一大这种变更既耗时又容易出问题。对于早期业务相对固定的系统来说这种“先定结构再存数据”的模式非常可靠这也是 MySQL 能统治互联网十几年的原因。但移动互联网时代来了之后业务迭代速度越来越快数据形态也变得多样化。一个用户的数据可能是简单的姓名和手机号也可能是包含收货地址、订单记录、设备信息、偏好标签等一长串内容的复合结构。如果用关系型数据库你可能需要拆成五六张表再用 JOIN 拼回来。而 MongoDB 的思路是数据是什么样我就按什么样存。一条文档就是一个完整的业务对象嵌套、数组、动态字段全部原生支持不需要预先定义结构。1.2 MongoDB 和 MySQL 的本质区别在哪里我整理了一张初学者最容易理解的对比表建议你收藏保存对比维度MySQL关系型MongoDB文档型数据模型行 列结构固定文档 字段结构灵活存储格式表格BSON类 JSON表/集合表Table集合Collection记录单位行Row文档Document字段变更需要 ALTER TABLE直接写入新字段即可关联数据外键 JOIN内嵌文档或引用适合场景事务性强、关系复杂迭代快、数据形态多变这里要特别说清楚一个点MongoDB 从 4.0 版本开始已经支持多文档事务了所以“它不支持事务”这个说法只适用于老旧版本。现在的 MongoDB 在金融、电商等要求强一致性的业务里也能站住脚只是大部分项目不会拿它当唯一的数据源更多是作为 MySQL/PostgreSQL 的补充存储那些结构多变的业务数据。1.3 初学阶段应该带着什么样的目标去学不要一上来就想把所有功能都学完。初识 MongoDB 这个阶段你只需要做到四件事第一能装好服务并且启动它第二能用命令行或者 Compass 连接上服务第三能理解“数据库—集合—文档”三层结构第四能完成最基础的增删改查操作。这四件事做扎实了后面再看索引、聚合、副本集、分片这些高级功能就会顺畅很多。我见过不少同学一上来就研究分片集群怎么搭结果连基本的查询都不会写最后越学越崩溃。学习路径一定要按“会用 → 懂原理 → 能优化”的顺序来一开始就追求高深的东西没有意义。2. 环境准备把你的 MongoDB 服务跑起来后端的各种组件最让人头疼的往往不是用而是装。MongoDB 的安装本身不算难但如果你不了解安装过程中的关键细节很容易卡在一些莫名其妙的报错上。下面我把 Windows 和 Linux/macOS 两种常见平台分开讲。2.1 Windows 上的安装步骤与版本选择MongoDB 官方提供了 Windows 平台的 MSI 安装包整体流程跟装普通软件差不多。但有几个关键点必须注意。第一是版本选择。截至我写这篇文章时MongoDB 最新的大版本已经到 7.x 了但很多教学平台和旧项目还在用 4.4.30 这个版本。如果你是跟着教程学建议优先选择与教程一致的版本避免因为版本差异导致命令或行为不一致。全新上手的话我推荐安装 6.0 或 7.0 的社区版功能更完善稳定性也经过了足够长时间的验证。官方下载地址是 MongoDB 官网的 Download Center选择 MSI 安装包即可。第二是安装过程中的组件选择。安装到“Choose Setup Type”这一步时建议选择“Complete”但装完之后要把 MongoDB Compass 的勾选取消掉节省下载时间因为 Compass 后面可以单独装。这里很多新人会踩坑——Compass 是一个图形化管理工具体积不小默认勾选会让整个安装过程非常慢。第三是安装目录和日志路径。MongoDB 在 Windows 上默认的日志路径是C:\Program Files\MongoDB\Server\版本号\log\数据目录默认是C:\Program Files\MongoDB\Server\版本号\data\。实际上正式使用的时候我建议你手动创建专门的目录比如D:\mongodb\data和D:\mongodb\log这样后面查找和维护都更方便。安装结束后MongoDB 默认会注册成 Windows 服务。你可以在服务管理器里找到MongoDB Server这个服务项确认它的状态是“正在运行”。2.2 安装失败的几个高发原因和处理方法“mongodb 安装失败”是搜索热词说明卡在这一步的人非常多。根据我自己的实测和网上看到的大量反馈最常见的失败原因主要有下面几类第一类安装到最后报错 2503/2505。这种问题一般出现在 Windows Installer 权限不足的场景下。解决办法是用管理员身份运行 cmd然后执行msiexec /package mongodb-win32-x86_64-xxx.msi来安装如果已经下载了安装包右键选择“以管理员身份运行”也可以解决。第二类服务启动失败日志里提示Data directory ... not found。这是因为 MongoDB 不会自动创建数据目录你需要在配置文件 mongod.cfg 里指定的路径必须真实存在。解决办法手动创建 data 目录或者修改配置文件然后重新启动服务。第三类端口 27017 被占用。MongoDB 默认监听 27017 端口如果本机已经装了其他 MongoDB 实例或者有程序占用了这个端口服务就会启动失败。执行netstat -ano | findstr 27017查看端口占用情况找到对应进程后将其结束或者修改 MongoDB 的端口配置。第四类缺少 VC 运行库。MongoDB 在 Windows 上依赖 Visual C Redistributable如果系统缺少相关的运行库安装包能装上但服务运行时会报错。装一下微软官方最新的“Visual C Redistributable for Visual Studio 2015-2022”通常就能解决。2.3 Linux/macOS 平台的快速安装方式Linux 和 macOS 上的安装相对简单一些推荐直接用包管理器。Ubuntu/Debian 系列可以导入官方密钥后通过 apt 安装也可以直接下载官方编译好的 tarball 解压使用。tarball 方式适合不想污染系统目录的场景下载解压后把 bin 目录加入 PATH 就行。macOS 用户可以优先使用 Homebrew命令是brew tap mongodb/brew brew install mongodb-community装好后用brew services start mongodb/brew/mongodb-community启动服务。不管在哪个平台装完之后都要验证一下 MongoDB 版本执行mongod --version如果能看到版本号输出说明核心组件已经就位。接下来就可以正式启动服务了。2.4 启动服务并测试连接Windows 上如果你已经通过 MSI 安装了服务直接执行net start MongoDB或者在服务管理器里启动即可。Linux 和 macOS 执行systemctl start mongod或brew services start mongodb-community。服务启动后新开一个终端执行mongosh如果能进入test或类似前缀的交互式 shell就说明客户端成功连接上了本地服务。注意老教程里的mongo命令在新版本中已经被mongosh取代了如果你安装的是 MongoDB 6.0执行mongo可能会提示找不到命令。这是新版本的一个重要变化。3. 核心概念先弄懂后面操作才不迷路很多人学习 MongoDB 卡壳不是因为命令不会敲而是因为脑子里没有建立一套对应的概念模型。所以这一节我先不讲命令花点时间把五个核心词讲清楚数据库、集合、文档、字段、主键。3.1 集合和文档到底是什么关系如果你学过关系型数据库可以用这样的类比来建立第一印象数据库对应数据库集合对应表文档对应行。但你必须明白这只是一个粗糙的类比它们之间的差异非常大。集合Collection可以理解成一个“装文档的容器”。集合不要求里面的文档结构一致你可以在一个集合里存放{name: 张三, age: 18}也可以存放{title: 标题, tags: [一, 二]}这在关系型数据库里是完全不可想象的。文档Document是 MongoDB 中的基本数据单元它本质上是一组键值对的集合格式非常接近 JSON。文档和集合关系可以类比为“文件”和“文件夹”。文件夹里可以放各种类型的文件文件本身也有自己的内部结构。MongoDB 的设计哲学就是这种自由度。3.2 BSON 和 JSON 到底有什么区别说到文档格式就绕不开 BSON。BSONBinary JSON是 MongoDB 用来存储文档的二进制序列化格式它在 JSON 的基础上增加了丰富的数据类型比如 Date日期、ObjectId主键、Decimal128高精度小数、Binary Data二进制数据等。你可以把 BSON 理解为“增强版的 JSON 二进制编码”。JSON 只能表达字符串、数字、布尔、数组和嵌套对象但业务里的时间、二进制内容、高精度金额就没办法精确表达了。BSON 解决的就是这个问题。还有一个非常实际的好处BSON 支持按路径快速访问字段。因为每条文档中的字段名会内嵌在存储结构中所以 MongoDB 查询{ address.city: 北京 }时不需要把整条文档反序列化完才能判断直接按 BSON 的结构导航过去就行。这个特性让嵌套查询保持了很好的性能。3.3 _id 主键是怎么生成和工作的关系型数据库的主键一般用自增整数MongoDB 的默认主键则是_id字段它的值是 ObjectId 类型。为什么不用自增整数原因很简单MongoDB 天生是为分布式而生的如果多个节点同时写入用一个全局自增 ID 会导致严重的协调压力网络开销大性能瓶颈明显。ObjectId 是一个 12 字节的十六进制字符串结构如下前 4 个字节生成时间的时间戳精确到秒中间 5 个字节机器标识码后面 2 个字节进程 ID最后 3 个字节自增计数器只要这四部分组合在一起全世界范围内几乎不会产生重复所以在分布式环境下每个节点都可以独立生成主键不需要中央协调器。你在初学阶段不需要手动创建_id当你执行插入操作时MongoDB 会自动帮你生成如果你自己传入了_id则按你传入的保存。3.4 用一张图理解整个存储结构我们用日常生活中的“图书馆”来类比整套逻辑这可能比你背概念更容易记住MongoDB 服务 一栋图书馆大楼数据库Database 大楼里的一个楼层集合Collection 楼层里的一个书架文档Document 书架上的一本书字段Field 书里的某一页内容你可以随时在一个书架上增加一本任意开本、任意内容的书而不需要像传统图书馆那样提前规定这本书必须是几开本、必须有哪几个章节。这种自由就是 MongoDB 设计的核心价值。4. 基本操作实战增删改查一次跑通理论再怎么讲不亲手敲一遍命令很难真正内化。这一节我用一个“用户管理”的实战案例把 MongoDB 最核心的增删改查完整过一遍。你可以准备一个已经跑起来的 MongoDB 服务边看边敲。4.1 进入数据库并选择集合启动mongosh之后你会看到 shell 提示符。这里默认会连接到一个叫test的数据库但你并不需要直接用它。执行use命令可以切换或创建数据库use shop如果shop数据库不存在这个命令也不会报错它只是把当前上下文切换到了shop等你真正写入第一条数据时数据库才会被实际创建。这种“懒创建”机制很符合 MongoDB 的直觉。在 MongoDB 中你可以直接操作一个不存在的集合。当你往某个集合里插入第一条文档时该集合就会被自动创建。换句话说你不需要像 MySQL 一样先CREATE DATABASE、CREATE TABLE直接写数据就行。4.2 插入文档和批量插入现在往shop数据库的users集合里插入一个用户db.users.insertOne({ name: 张三, age: 28, email: zhangsanexample.com, tags: [普通用户, 会员], address: { city: 北京, street: 某某路 100 号 } })执行之后你会看到返回结果里有acknowledged: true和insertedId的信息。acknowledged: true表示写入操作已被 MongoDB 确认这是默认的写入关注级别insertedId则是本次插入文档对应的_id。如果需要一次插入多条文档用insertManydb.users.insertMany([ { name: 李四, age: 22, email: lisiexample.com }, { name: 王五, age: 35, email: wangwuexample.com, vip: true } ])注意第二条文档多了一个vip字段而第一条没有这在 MongoDB 中完全合法。你不需要给集合加列也没有必要给不缺的文档补空值每条文档只要包含自己需要的数据就足够了。这就是文档数据库相对关系型数据库最直观的优势。4.3 查询文档最常用的筛选方式查询语法是 MongoDB 里最需要花功夫的部分但初学阶段只需掌握find的三种基础用法。第一种查全部。db.users.find()不加任何条件时会返回集合里所有文档。如果你觉得输出太乱可以调用.pretty()让文档以多行格式显示db.users.find().pretty()第二种按条件查。db.users.find({ age: 28 }) db.users.find({ address.city: 北京 })第一条命令会匹配age等于 28 的文档第二条按嵌套字段过滤字段路径之间用引号包住并以点号连接。对初学阶段来说这是很重要的一个格式后面查嵌套文档时会一直用到。第三种带上比较运算符。MongoDB 的比较运算符都以$开头例如db.users.find({ age: { $gte: 25 } }) db.users.find({ age: { $lt: 30, $gte: 20 } })$gte表示大于等于$lt表示小于。你可以组合多个条件实现“20 到 30 岁之间”的范围过滤。如果你只想返回部分字段可以通过第二个参数做投影指定字段返回 1不返回的字段写 0db.users.find({ age: { $gte: 25 } }, { name: 1, email: 1, _id: 0 })这条命令只返回符合条件的用户名字和邮箱不返回_id这样可以减少网络传输量。初学阶段可能体会不深但数据量上来以后这个优化很重要。4.4 更新文档修改单条与批量修改更新是新人最容易出错的环节核心在于理解更新操作符。先看基本用法。把张三的年龄改成 29db.users.updateOne( { name: 张三 }, { $set: { age: 29 } } )updateOne的第一个参数是筛选条件第二个参数是更新操作。$set表示“把指定字段改成新值”。如果某条文档没有这个字段$set会自动补上这个字段这一点非常实用。批量更新多条文档时用updateManydb.users.updateMany( { age: { $lt: 30 } }, { $set: { level: young } } )这条命令会找出所有年龄小于 30 的用户给它们统一加上一个level字段。这里必须提醒一个关键坑如果你在第二个参数里直接写了一个文档而不是用$set这类更新操作符MongoDB 会用新的文档直接替换整条原文档而不是部分更新。例如db.users.updateOne( { name: 张三 }, { age: 30 } )这条命令执行后张三的文档会变成只有age: 30这一个字段其他字段全部丢失。很多新手在这里栽过跟头。原因在于 MongoDB 的更新操作在语义上分两种替换整个文档以及通过操作符做局部更新。不加操作符就会走进替换逻辑。因此只要不是刻意要覆盖整条文档更新操作都建议使用$set。4.5 删除文档按条件删除与清空集合删除操作相对简单直接给命令。db.users.deleteOne({ name: 李四 }) db.users.deleteMany({ age: { $lt: 25 } })deleteOne只删除第一个符合条件的文档deleteMany会删除所有符合条件的文档。如果deleteMany的参数是空对象{}那这个集合里的文档会被全部删光。还有一个容易混淆的删除操作db.users.drop()是直接把整个集合删掉包括集合里的所有文档和索引。如果你只是想清空数据但保留集合应该用db.users.deleteMany({})不要用drop()。这两者的区别在日常操作中影响很大。4.6 写操作后的常见报错速查我在初学阶段遇到过不少报错这里整理几个出现频率最高的报错信息原因解决办法MongoServerError: E11000 duplicate key error collection插入或更新操作违反了唯一索引约束检查_id或其他带唯一索引的字段是否重复TypeError: db.users.updateOne is not a function你连接的 MongoDB 服务版本过旧不支持新 API升级 MongoDB 到 3.2 以上版本MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017本地 MongoDB 服务没有启动或者端口不对确认服务已启动检查配置文件端口Query failed with error code 2查询语句的语法有问题一般是少了大括号或者引号检查命令行中的括号是否匹配这些报错在实际操作里几乎一定会遇到先提前打好预防针到时候就不会慌了。5. 用好 MongoDB Compass可视化操作与数据预览命令行操作虽然很“硬核”但如果你搞不清数据库里到底存了什么MongoDB Compass 会是你很好的帮手。Compass 是 MongoDB 官方出品的图形化管理工具可以直观地查看集合中的文档、执行查询、管理索引甚至直接做增删改查。5.1 Compass 的核心功能有哪些Compass 最核心的价值是“让数据可见”。连接上服务后你可以在左侧看到所有数据库列表展开数据库后能看到所有集合。点击一个集合右边会按页展示文档内容和 Tailwind 一样清晰直观。除此之外Compass 还内置了一个完整的查询构建器。你不需要记语法只需要在过滤框里输入条件 JSON比如{ age: { $gte: 25 } }它会实时返回查询结果。这个功能特别适合初学阶段——你可以先在 Compass 里验证自己的查询条件是否正确确认无误后再去命令行里执行。5.2 Compass 的安装与连接方式如果你在安装 MongoDB 时取消了 Compass可以单独去官网下载对应版本的 Compass 安装包。安装完成后打开 Compass在连接串输入框里填上mongodb://localhost:27017然后点击 Connect 就能连上本地服务。如果你的 MongoDB 设置了用户名和密码连接串还需要带上认证信息mongodb://admin:passwordlocalhost:27017/?authSourceadmin初学阶段不需要设置认证直接用默认连接即可。这里要提醒一下Compass 的版本最好和 MongoDB 服务版本保持兼容否则可能出现连接不上或界面异常的问题。如果遇到这类问题先看服务日志再检查端口连通性。5.3 Compass 里的增删改查操作体验Compass 对初学者最友好的地方在于所有写操作都不需要手敲命令。你可以在文档列表右侧点击“Insert Document”直接添加 JSON 数据鼠标悬停在某条文档上可以编辑单个字段的值删除文档时只需点击右侧的垃圾桶图标。Compass 会自动帮你把操作转换成对应的 MongoDB 命令你还能看到它生成的脚本内容。我的建议是先用 Compass 建立操作直觉然后在mongosh里手动敲一遍同样的操作。这样两边对照着学记忆会非常深刻。6. 入门阶段最容易踩的坑与后续方向到这里你可能已经完成了“初识 MongoDB”的最后一步——能插入数据、能查询数据、能修改和删除数据。但学完基础只是开始下面这些经验是我踩过不少坑之后总结出来的。6.1 初学阶段最容易踩的 5 个坑第一个坑Windows 上装好 MongoDB 后直接在 cmd 里敲mongod启动然后发现窗口一直停留在等待连接状态就以为卡死了。实际上mongod是服务端进程默认会一直运行等待连接要操作数据应该另外开一个窗口运行mongosh。如果你把mongod关掉了服务也会跟着停掉。第二个坑数据库路径和配置不匹配。手动启动mongod时如果不指定--dbpath默认会使用C:\data\db如果这个目录不存在mongod会启动失败。注册成 Windows 服务后它会读取mongod.cfg里配置的路径。所以要么统一走服务方式启动要么在启动命令里显式指定dbpath。第三个坑胡乱使用use切换数据库后发现数据“丢了”。这通常是因为你切换到了错误的数据库或者你以为use会创建数据库但实际上没有插入数据。记住一点在 MongoDB 里只有写入第一条数据后数据库才会真正出现如果只是use xxx然后查询返回空是正常现象。第四个坑更新数据时忘记$set导致整个文档被覆盖。这个问题我在前面已经详细说明过这是对新手影响最大的一个操作陷阱。第五个坑字符编码问题。在 Windows 的 cmd 里输入中文数据时有时会显示乱码或插入失败。解决方案是不要依赖 cmd 的默认代码页直接使用 MongoDB Compass或者使用 Windows Terminal 并切换到 UTF-8 编码。开发写代码时连接字符串和文件都必须保持 UTF-8 编码否则写入中文后查询会出现不可预知的异常。6.2 关于版本选择的一些个人建议MongoDB 版本更新速度很快新版本会带来新的特性和性能提升但也会移除一些旧命令。稳妥起见入门阶段我建议选择 6.0 或 7.0 的稳定版本这是当前社区使用最多的版本范围遇到问题也能搜到最多解决方案。另外官方文档永远是第一手资料。国内技术博客普遍存在抄来抄去的问题很多细节已经过时而你只要能在官方文档里检索对应版本的 API就能避免踩坑。尤其要注意查询语法、更新操作符、聚合管道的细节经常因版本不同而变化你在搜索时最好把版本号一起带上例如“mongodb 7.0 updateMany with $set”这样搜到的结果才更准确。6.3 学完基础后下一步可以怎么走如果你已经把增删改查练熟了下一个阶段建议按这个顺序学习第一学习索引。索引是 MongoDB 性能优化绕不开的一环。你可以为高频查询的字段创建单字段索引为组合查询创建复合索引还可以尝试 TTL 索引来实现数据自动过期。这是从“能跑”到“跑得快”的必经之路。第二学习聚合管道。它相当于 MongoDB 里的“GROUP BY JOIN 复杂计算”综合体。用一个 JSON 数组串联多个阶段就可以在数据库端完成分组、排序、关联、投影等操作。这是处理统计报表类任务的利器。第三学习副本集和分片。当数据量和并发量上来之后单机可能扛不住这时就需要副本集来做高可用分片来做水平扩展。这些内容不建议一上来就学但你应该知道 MongoDB 具备这些能力等真到需要时再深入也不迟。第四学习官方驱动。实际开发中你不会一直用命令行操作数据库而是要借助语言驱动。Python 里用 pymongoNode.js 里用 mongooseJava 里用官方 Java Driver。把命令行的操作逻辑迁移到驱动代码中很快就能上手。6.4 回归初心MongoDB 到底适不适合你的项目学完基础之后你可能会纠结一个问题MongoDB 适合放在什么项目里用根据我自己的项目经验它特别适合数据形态不固定、业务快速迭代、读取频繁、写入压力大的场景。比如用户行为日志、商品信息管理、物联网设备上报数据、社交内容社区里的帖子与评论等。而强事务、高一致性、复杂关联报表等场景关系型数据库依然更合适。所以“初识 MongoDB”不只是一个技术实操任务更是一次数据思维模式的更新。你不需要在 MongoDB 和 MySQL 之间分个你死我活真正的高手懂得在同一个系统里让两种数据库各司其职、取长补短。我自己的习惯是核心业务用 PostgreSQL 或者 MySQL存储强一致性的订单和账户数据灵活多变、结构不固定的数据存 MongoDB比如用户扩展资料、操作日志、消息记录。两个数据库配合使用系统既有关系型数据库的可靠性又能享受到文档数据库的灵活性。回到开头那句话MongoDB 真正吸引人的地方不是“不用写 SQL”而是它让数据存储回归到了“贴近业务直觉”的状态。你把这个心态建立起来后面无论学到多深的功能都不会觉得别扭了。这篇内容就是一步步带你把环境、概念、基本操作全部跑通后面的路你可以按照自己的实际需求继续探索。
返回列表