赞
踩
简介: 本文总结了MongoDB 4.X在mongo shell客户端涉及的对文档一些基本的增删改查操作,即CRUD操作。

创建(Create Operations)也叫插入操作,当集合不存在时,插入操作同时也会创建集合。MongoDB提供以下几种插入文档方法:
在平时的使用当中,db.collection.insert()是我用得最多的文档插入方式,具体的语法格式如下:
- db.collection.insert(
- <document or array of documents>,
- {
- writeConcern: <document>,
- ordered: <boolean>
- }
- )
参数说明:
ordered:指定文档是否按顺序插入(可选),默认为true;
如果插入的文档当中没有指定_id字段,则MongoDB会自动为文档生成具有唯一ObjectId值的字段_id。
使用示例:
- // 没有指定_id字段的插入单个文档
- db.products.insert( { item: "card", qty: 15 } );
- // 指定_id字段的插入单个文档
- db.products.insert( { _id: 10, item: "box", qty: 20 } );
- // 插入多个文档,不进行排序,多个文档包含在数组[]中
- db.products.insert(
- [
- { _id: 11, item: "pencil", qty: 50, type: "no.2" },
- { item: "pen", qty: 20 },
- { item: "eraser", qty: 25 }
- ]
- );
- // 插入多个文档,并进行排序
- db.products.insert(
- [
- { _id: 20, item: "lamp", qty: 50, type: "desk" },
- { _id: 21, item: "lamp", qty: 20, type: "floor" },
- { _id: 22, item: "bulk", qty: 100 }
- ],
- { ordered: false }
- );

语法格式如下:
- db.collection.insertOne(
- <document>,
- {
- writeConcern: <document>
- }
- )
参数说明:参考db.collection.insert()的参数说明。
使用示例:
- // 单行插入文档,关于_id字段指定与否也与db.collection.insert()一致
- db.products.insertOne( { item: "card", qty: 15 } );
语法格式如下:
- db.collection.insertMany(
- [ <document 1> , <document 2>, ... ],
- {
- writeConcern: <document>,
- ordered: <boolean>
- }
- )
参数说明:参考db.collection.insert()的参数说明。
使用示例:参考db.collection.insert()的参数说明。
db.collection.insert()在插入文档成功之后返回的信息相对较为简洁:
- db.products.insert( { item: "card", qty: 15 } );
- WriteResult({ "nInserted" : 1, "writeConcernError" : [ ] })
db.collection.insertOne()和db.collection.insertMany()返回的信息较为详细:
- db.products.insertOne( { item: "card", qty: 15 } );
- {
- "acknowledged": true,
- "insertedId": ObjectId("5eccbd214139000074003be8")
- }
- db.products.insertMany( [
- { _id: 10, item: "large box", qty: 20 },
- { _id: 11, item: "small box", qty: 55 },
- { _id: 12, item: "medium box", qty: 30 }
- ] );
- {
- "acknowledged": true,
- "insertedIds": [
- 10,
- 11,
- 12
- ]
- }

查询(Read Operations)读操作,是对集合中已存在的文档进行查询,即对应关系型数据库当中的select操作,比如MySQL,MongoDB提供以下几种主要查询文档方法:
pretty()方法。来自官方文档的测试数据:
- db.inventory.insertMany([
- { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
- { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
- { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
- { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
- { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
- ]);
db.collection.find()可以说是使用频率最高的方法了,可以用来查询数据库集合当中的文档。
语法格式如下:
db.collection.find(<query>, <projection>)
projection:指定查询结果集中需要显示的字段。
_id字段是默认显示的,如果不想显示,则显式指定{"_id" : 0}。
查询所有文档:
db.inventory.find()
或
db.inventory.find({})
db.collection.findOne()方法显示符合条件查询的第一条文档,接受的参数与db.collection.find()方法一致。
通常对文档的查询,是需要带条件的,而很少使用到不带条件的全文档检索,以下总结了几种常使用的查询操作符:
比较操作符
比较操作符涉及的操作如下表所示:
| 名称 | 说明 |
|---|---|
| $eq | 与指定值相等 |
| $gt | 大于指定的值 |
| $gte | 大于或等于指定的值 |
| $in | 指定的值在数组中 |
| $lt | 小于指定的值 |
| $lte | 小于或等于指定的值 |
| $ne | 所有不等于指定的值 |
| $nin | 指定的值不在数组中 |
使用示例:
- // $eq:等值查询 SQL: SELECT * FROM inventory WHERE status = "D";
- db.inventory.find( { status: "D" } )
- // $ne 同$eq
- // $gt:范围查询(以大于为例) SQL: SELECT * FROM inventory WHERE qty > 30;
- db.inventory.find( { qty: { $gt: 30 } } )
- // $gte、$lt、$lte 同$gt
- // $in:或查询,可使用or代替 SQL: SELECT * FROM inventory WHERE status in ("A", "D")
- db.inventory.find( { status: { $in: [ "A", "D" ] } } )
- // $nin 同$in
逻辑操作符
逻辑操作符涉及的操作如下表所示:
| 名称 | 说明 |
|---|---|
| $and | 指定查询同时满足多个条件查询子句 |
| $not | 指定查询不满足条件查询子句 |
| $nor | 指定查询无法满足多个条件查询子句 |
| $or | 指定查询满足其中某个条件查询子句 |
使用示例:
- // $and: 逻辑与查询 SQL: SELECT * FROM inventory WHERE status = "A" AND qty < 30;
- db.inventory.find( { $and: [ { status: { $eq: "A" }, qty: { $lt: 30 } } ] } )
- // $not: 不符合查询 SQL: SELECT * FROM inventory WHERE status <> "A";
- db.inventory.find( { status: { $not: { $eq: "A" } } } )
- /*
- $nor: 无法同时满足多个条件查询,字段不存在时也符合 SQL: SELECT * FROM inventory WHERE status <> "A" AND qty > 30;
- 符合以下条件之一都会出现在结果集中:
- 1.文档包含status和qty字段并且符合条件;
- 2.文档包含status字段并且符合条件,不包含qty字段;
- 3.文档不包含status字段,包含qty字段并且符合条件;
- 4.文档不包含status字段和qty字段。
- */
- db.inventory.find( { $nor: [ { status: { $eq: "A" } }, { qty: { $lt: 30 } } ] } )
- // $or: 逻辑或查询 SQL: SELECT * FROM inventory WHERE status = "A" OR qty < 30;
- db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
元素操作符
元素操作符主要涉及的操作如下表所示:
| 名称 | 说明 |
|---|---|
| $exists | 指定查询文档是否有对应的字段 |
| $type | 指定查询文档的某个字段是否是对应类型 |
使用示例:
- // $exists: 是否存在指定字段查询
- db.inventory.find( { price: { $exists: true } } )
- // $type: 字段是否是指定类型查询
- db.inventory.find( { "qty": { $type: "double" } } )
评估操作符
评估操作符主要涉及的操作如下表所示,更多操作符可以参考官方文档:https://docs.mongodb.com/manual/reference/operator/query-evaluation/。
| 名称 | 说明 |
|---|---|
| $expr | 为同一个文档中的字段指定表达式并且符合条件的查询,比如比较同一文档当中两个字段的值 |
| $mod | 为字段值取模并且符合条件的查询 |
为了更好的使用这两个主要的操作符,额外创建个文档:
- db.monthlyBudget.insertMany([
- { "_id" : 1, "category" : "food", "budget": 400, "spent": 450 },
- { "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 },
- { "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 },
- { "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 },
- { "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
- ]);
使用示例:
- // $expr: 允许使用聚合表达式,这里以$gt为例,更多表达式参考 https://docs.mongodb.com/manual/meta/aggregation-quick-reference/#aggregation-expressions
- db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
- // $mod: 对字段所在值进行取模运算,显示符合条件的查询,如qty字段值对4取模,并且余数为0
- db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )
更新(Update Operations)是对已存在的文档进行修改操作,MongoDB提供以下几种主要更新文档方法:
根据update指定的表达式可以修改文档中符合条件的字段或代替整个文档。具体的语法格式如下:
- db.collection.update(
- <query>, //查询表达式
- <update>, //更新表达式
- {
- upsert: <boolean>,
- multi: <boolean>,
- writeConcern: <document>,
- collation: <document>,
- arrayFilters: [ <filterdocument1>, ... ],
- hint: <document|string> // 版本4.2新增
- }
- )
参数说明:
upsert: true并且集合中没有符合查询条件的文档,查询条件中有关于字段_id指定了.分隔符的,并不会插入新的文档;update:主要包含三种格式
<field1>: <value1>对;使用示例:
使用示例将通过使用两种场景进行,一是没有使用参数选项upsert,二是使用参数选项upsert。
- // 测试数据
- db.books.remove({});
- db.books.insertMany([
- {
- "_id" : 1,
- "item" : "TBD",
- "stock" : 0,
- "info" : { "publisher" : "1111", "pages" : 430 },
- "tags" : [ "technology", "computer" ],
- "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
- "reorder" : false
- },
- {
- "_id" : 2,
- "item" : "XYZ123",
- "stock" : 15,
- "info" : { "publisher" : "5555", "pages" : 150 },
- "tags" : [ ],
- "ratings" : [ { "by" : "xyz", "rating" : 5 } ],
- "reorder" : false
- }
- ]);
- /* 使用选项参数 upsert: true
- 1、如果查询表达式找到匹配的文档,则执行更新操作;
- 2、如果查询表达式没有找到匹配的文档,则执行插入操作;
- */
- db.books.update(
- { item: "ZZZ135" }, // 查询表达式
- { // 更新或替换文档
- item: "ZZZ135",
- stock: 5,
- tags: [ "database" ]
- },
- { upsert: true }
- );
- // 1.使用更新操作表达式
- /* $set操作符
- 1、查询表达式指定需要更新的文档 _id;
- 2、$inc操作符: stock的字段值+5;
- 3、$set操作符: 替换item字段值,替换嵌入文档info的publisher字段值,替换tags字段值,替换数组ratings的第二个元素值
- */
- db.books.update(
- { _id: 1 },
- {
- $inc: { stock: 5 },
- $set: {
- item: "ABC123",
- "info.publisher": "2222",
- tags: [ "software" ],
- "ratings.1": { by: "xyz", rating: 3 }
- }
- }
- );
- 更新之后的文档:
- {
- "_id" : 1,
- "item" : "ABC123",
- "stock" : 5,
- "info" : { "publisher" : "2222", "pages" : 430 },
- "tags" : [ "software" ],
- "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
- "reorder" : false
- }
- // 2.为已存在的数组添加元素
- // $push操作符: 为指定文档数组ratings添加一个元素
- db.books.update(
- { _id: 2 },
- {
- $push: { ratings: { "by" : "jkl", "rating" : 2 } }
- }
- );
- 更新之后的文档:
- {
- "_id" : 2,
- "item" : "XYZ123",
- "stock" : 15,
- "info" : {
- "publisher" : "5555",
- "pages" : 150
- },
- "tags" : [ ],
- "ratings" : [
- { "by" : "xyz", "rating" : 5 },
- { "by" : "jkl", "rating" : 2 }
- ],
- "reorder" : false
- }
- // 3.文档移除字段
- // $unset操作符: 移除文档的指定字段,为_id:1文档移除tags字段
- db.books.update( { _id: 1 }, { $unset: { tags: 1 } } );
- 更新后的文档:
- {
- "_id" : 1,
- "item" : "TBD",
- "stock" : 0,
- "info" : {
- "publisher" : "1111",
- "pages" : 430
- },
- "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
- "reorder" : false
- }
- // 4.替换整个文档
- // 替换_id:2的文档
- db.books.update(
- { _id: 2 },
- {
- item: "XYZ123",
- stock: 10,
- info: { publisher: "2255", pages: 150 },
- tags: [ "baking", "cooking" ]
- }
- );
- 更新后的文档:
- {
- "_id" : 2,
- "item" : "XYZ123",
- "stock" : 10,
- "info" : { "publisher" : "2255", "pages" : 150 },
- "tags" : [ "baking", "cooking" ]
- }
- // 5.更新多个文档
- db.books.update(
- { stock: { $lte: 10 } },
- { $set: { reorder: true } },
- { multi: true }
- );
- 更新后的全部文档:
- [
- {
- "_id" : 1,
- "item" : "ABC123",
- "stock" : 5,
- "info" : {
- "publisher" : "2222",
- "pages" : 430
- },
- "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
- "reorder" : true
- }
- {
- "_id" : 2,
- "item" : "XYZ123",
- "stock" : 10,
- "info" : { "publisher" : "2255", "pages" : 150 },
- "tags" : [ "baking", "cooking" ],
- "reorder" : true
- }
- ]

- /* 使用选项参数 upsert: true
- 1、如果查询表达式找到匹配的文档,则执行更新操作;
- 2、如果查询表达式没有找到匹配的文档,则执行插入操作;
- */
- // 1.插入未符合更新条件的文档
- db.books.update(
- { item: "ZZZ135" },
- {
- item: "ZZZ135",
- stock: 5,
- tags: [ "database" ]
- },
- { upsert: true }
- );
- 因为集合并未满足条件的文档,则插入的文档为:
- {
- "_id" : ObjectId("5da78973835b2f1c75347a83"),
- "item" : "ZZZ135",
- "stock" : 5,
- "tags" : [ "database" ]
- }
- // 2.插入未符合更新条件并且基于更新操作符的文档
- // 如果没有符合更新查询条件,并且使用的是更新操作符,则会基于当前的查询条件和更新操作符字段插入新的文档
- db.books.update(
- { item: "BLP921" },
- {
- $set: { reorder: false },
- $setOnInsert: { stock: 10 }
- },
- { upsert: true }
- );
- 新插入的文档为:
- {
- "_id" : ObjectId("5da79019835b2f1c75348a0a"),
- "item" : "BLP921",
- "reorder" : false,
- "stock" : 10
- }
- // 3.插入未符合更新条件并且基于聚合管道的文档
- // 关于聚合管道请参考官方文档:https://docs.mongodb.com/manual/reference/method/db.collection.update/#update-with-aggregation-pipeline
- // 4.插入未符合更新条件并且同时联合多文档操作符的文档
- 如果不符合查询条件,则只会插入单个文档
- db.books.update(
- { "info.publisher": "Self-Published" },
- {
- $set: { reorder: false, tags: [ "literature", "hardcover" ], stock: 25 }
- },
- { upsert: true, multi: true }
- );
- 新插入的文档:
- {
- "_id" : ObjectId("5db337934f670d584b6ca8e0"),
- "info" : { "publisher" : "Self-Published" },
- "reorder" : false,
- "stock" : 25,
- "tags" : [ "literature", "hardcover" ]
- }

根据update指定的参数可以修改文档中符合条件的字段或代替整个文档,与db.collection.update()不同的是每次只更新单个文档。
语法格式如下:
- db.collection.updateOne(
- <filter>,
- <update>,
- {
- upsert: <boolean>,
- writeConcern: <document>,
- collation: <document>,
- arrayFilters: [ <filterdocument1>, ... ],
- hint: <document|string>
- }
- )
参数说明:
参考db.collection.update()的参数说明。
使用示例:
// 参考db.collection.update()
根据update指定的参数可以修改文档中符合条件的字段或代替整个文档,与db.collection.updateOne()不同的是更新所有符合条件的文档。
语法格式如下:
- db.collection.updateMany(
- <filter>,
- <update>,
- {
- upsert: <boolean>,
- writeConcern: <document>,
- collation: <document>,
- arrayFilters: [ <filterdocument1>, ... ],
- hint: <document|string>
- }
- )
参数说明:
参考db.collection.update()的参数说明。
使用示例:
// 参考db.collection.update()
删除是指对集合当中已存在的文档进行清除操作,MongoDB提供以下几种主要删除文档方法:
根据filter选项条件删除集合中的单个文档,具体语法格式如下:
- db.collection.deleteOne(
- <filter>,
- {
- writeConcern: <document>,
- collation: <document>
- }
- )
参数说明:
db.collecion.find()中的<query>;使用示例:
- // 删除指定条件的单个文档
- db.orders.deleteOne( { "_id" : 1 } );
- { "acknowledged" : true, "deletedCount" : 1 }
根据filter选项条件删除集合中的单个文档,具体语法格式如下:
- db.collection.deleteMany(
- <filter>,
- {
- writeConcern: <document>,
- collation: <document>
- }
- )
参数说明:参考db.collection.deleteOne()的参数说明。
使用示例:
- // 删除指定条件的多个文档
- db.orders.deleteMany( {"cust_id" : "Cam Elot"} );
- { "acknowledged" : true, "deletedCount" : 2 }
注意: 如果是对固定集合进行删除文档操作则会报错,固定集合的清除操作使用方法db.collection.drop()。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。