LabHub
学习 学习路径 课程

MongoDB — 文档数据库的判断

MongoDB — 内嵌与执行计划

在 LabHub 中继续学习

目标

在 Pod 内运行的真实 MongoDB 8.0 上插入、查询文档,创建索引,执行聚合, 设置 schema,并练习嵌入式建模。最后读取执行计划,并把其中的数字记录下来。

连接

mongosh labdb

使用 labdb。PostgreSQL 也在同一个 Pod 中运行,所以可以直接使用 psql—— 把两个数据库并排放置,分别解决同一个问题,差异会清晰得多。

结果文件

有些步骤需要把结果保存到文件中。请先执行 mkdir -p /root/work/mongo。 在 shell 中保存 JSON 时,可以这样写:

mongosh --quiet labdb --eval 'JSON.stringify(db.items.find({},{_id:0}).toArray())'   > /root/work/mongo/02-query.json

插入文档——值也可以是数组

使用 mongosh labdb 连接。通过 db.items.insertMany([...]) 插入至少 5 条记录。每个文档都要有 name(字符串)、qty(数字)和 tags(数组)。其中一个名称必须是 빨간 배낭

items 中至少有 5 条记录;每个文档都有 name、qty 和 tags(数组)

只取需要的字段

查找 qty 大于 0 的文档,并且只投影 name 和 qty_id: 0)。把结果以 JSON 数组保存到 /root/work/mongo/02-query.json。使用 mongosh --quiet --evalJSON.stringify 会更方便。

02-query.json 包含 qty>0 的文档,并且每条只含 name 和 qty

创建索引并观察执行计划是否变化

执行 db.items.createIndex({name: 1})。然后运行 db.items.find({name:'빨간 배낭'}).explain(),确认计划中是否出现 IXSCAN。

存在 name 索引,并且该查询使用 IXSCAN

只修改一个字段

빨간 배낭qty 改为 10。必须使用 $set——如果整体替换文档,未写出的字段会消失。

qty 为 10,并且 name 与 tags 保持不变

展开数组并按标签分组

$unwind 展开 tags,再用 $group 计算每个标签的 qty 总和。把结果保存到 /root/work/mongo/05-bytag.json,格式为 [{_id, total}, ...]

05-bytag.json 中各标签的总和与实际数据一致

文档数据库也要设置 schema

使用 db.createCollection('orders', {validator: {$jsonSchema: {...}}}),把 qty 设为必填数字。规则只写下来却没有真正拦截,就等于不存在——请实际插入字符串,确认它会被拒绝。

orders 具有 $jsonSchema 验证,错误类型会被实际拒绝

一起读取的数据应嵌入保存

orders 中插入一条订单,把商品作为 lines 数组嵌入其中(至少 2 条,每项有 name 和 qty)。同时提供 qty,使其通过第 6 步的验证。可以用 db.orders.find({'lines.name': ...}) 查询数组内部。

一条订单文档中至少有 2 条 lines,并可通过 lines.name 查询

读取执行计划并记录数字

/root/work/mongo/08-explain.txt 中比较有索引时(IXSCAN)与无索引时(COLLSCAN)的结果。必须包含 explain('executionStats')totalDocsExamined具体数字

08-explain.txt 同时包含 IXSCAN、COLLSCAN 和数字