MongoDB 4.X CRUD基本操作-阿里云开发者社区

开发者社区> 幸运码发放> 正文

MongoDB 4.X CRUD基本操作

简介:
+关注继续查看

MongoDB 4.X CRUD基本操作

mangoDB
目录

创建(Create Operations)
db.collection.insert()
db.collection.insertOne()
db.collection.insertMany()
关于返回确认信息
查询(Read Operations)
db.collection.find()
db.collection.findOne()
条件查询操作符
更新(Update Operations)
db.collection.update()
db.collection.updateOne()
db.collection.updateMany()
删除(Delete Operations)
db.collection.deleteOne()
db.collection.deleteMany()
总结
参考
正文

本文总结了MongoDB 4.X在mongo shell客户端涉及的对文档一些基本的增删改查操作,即CRUD操作。主要结合了自己平时使用MongoDB的操作命令,更详细的命令可以参考官方文档: https://docs.mongodb.com/manual/crud/ 。

回到顶部
创建(Create Operations)
创建(Create Operations)也叫插入操作,当集合不存在时,插入操作同时也会创建集合。MongoDB提供以下几种插入文档方法:

db.collection.insert():在指定集合中插入单个或多个文档。
db.collection.insertOne():在指定集合中插入单个文档(版本3.2新增)。
db.collection.insertMany():在指定集合中插入多个文档(版本3.2新增)。
回到顶部
db.collection.insert()
在平时的使用当中,db.collection.insert()是我用得最多的文档插入方式,具体的语法格式如下:

db.collection.insert(
,
{

 writeConcern: <document>,
 ordered: <boolean>

}
)
参数说明:

document:指定一个或多个文档;
writeConcern:文档写入确认级别(可选),关于读写策略确认级别,以后再进行讨论;
ordered:指定文档是否按顺序插入(可选),默认为true;
当指定为true时,插入多个文档时将文档排序保存在一个数组中进行插入,如果其中有一个文档插入失败,则会导致数组中余下的文档不进行插入操作;
当指定为false时,插入多个文档时将文档不进行排序保存在一个数组中进行插入,如果其中有一个文档插入失败,则不影响数组中余下的文档进行插入操作。
如果插入的文档当中没有指定_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()
语法格式如下:

db.collection.insertOne(
,
{

  writeConcern: <document>

}
)
参数说明:

参考db.collection.insert()的参数说明。

使用示例:

// 单行插入文档,关于_id字段指定与否也与db.collection.insert()一致
db.products.insertOne( { item: "card", qty: 15 } );
回到顶部
db.collection.insertMany()
语法格式如下:

db.collection.insertMany(
[ , , ... ],
{

  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)
查询(Read Operations)读操作,是对集合中已存在的文档进行查询,即对应关系型数据库当中的select操作,比如MySQL,MongoDB提供以下几种主要查询文档方法:

db.collection.find():查询指定集合中满足条件的一个或多个文档和视图;
db.collection.findOne():查询指定集合中满足条件的第一个文档,并以格式化方式展现,通过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()可以说是使用频率最高的方法了,可以用来查询数据库集合当中的文档。

语法格式如下:

db.collection.find(, )
query:查询表达式;
projection:指定查询结果集中需要显示的字段。
Col_name:1|true 代表显示该字段;
Col_name:0 | false 代表不显示该字段。
_id字段是默认显示的,如果不想显示,则显式指定{"_id" : 0}。

查询所有文档:

db.inventory.find()

db.inventory.find({})
回到顶部
db.collection.findOne()
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)
更新(Update Operations)是对已存在的文档进行修改操作,MongoDB提供以下几种主要更新文档方法:

db.collection.update():更新或替换集合中符合条件的一个或多个文档;
db.collection.updateOne():只更新集合中符合条件的第一个文档,即使有多个文档(版本3.2新增);
db.collection.updateMany():更新集合中所有符合条件的文档(版本3.2新增)。
回到顶部
db.collection.update()
根据update指定的表达式可以修改文档中符合条件的字段或代替整个文档。具体的语法格式如下:

db.collection.update(
, //查询表达式
, //更新表达式
{

 upsert: <boolean>,
 multi: <boolean>,
 writeConcern: <document>,
 collation: <document>,
 arrayFilters: [ <filterdocument1>, ... ],
 hint:  <document|string>                   // 版本4.2新增

}
)
参数说明:

query:更新文档的查询表达式;如果指定了参数upsert: true并且集合中没有符合查询条件的文档,查询条件中有关于字段_id指定了.分隔符的,并不会插入新的文档;
update:主要包含三种格式
1.更新文档:只包含更新操作符表达式;
2.替换文档:只包含: 对;
3.聚合管道:版本4.2新增,详细参考官方文档。
upsert:当query查询条件没符合更新的文档,就新创建文档(可选),默认值为false;
multi:是否更新多个符合条件的文档(可选),默认值为false,只更新符合条件的第一个文档;
writeConcern:参考db.collection.insert()相同参数说明;
collation:指定校对规则(可选,版本3.4新增);
arrayFilters:文档数组更新过滤操作符(可选,版本3.6新增);
详细参考:https://docs.mongodb.com/manual/reference/method/db.collection.update/#specify-arrayfilters-for-array-update-operations

hint:采用文档或字符串的形式指定适用于查询表达式的索引,如果索引不存在则报错(可选,版本4.2新增)。
使用示例:

使用示例将通过使用两种场景进行,一是没有使用参数选项upsert,二是使用参数选项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

}
]
使用upserts选项
/* 使用选项参数 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" ]
}
回到顶部
db.collection.updateOne()
根据update指定的参数可以修改文档中符合条件的字段或代替整个文档,与db.collection.update()不同的是每次只更新单个文档。

语法格式如下:

db.collection.updateOne(
,
,
{

 upsert: <boolean>,
 writeConcern: <document>,
 collation: <document>,
 arrayFilters: [ <filterdocument1>, ... ],
 hint:  <document|string>        

}
)
参数说明:

参考db.collection.update()的参数说明。

使用示例:

// 参考db.collection.update()
回到顶部
db.collection.updateMany()
根据update指定的参数可以修改文档中符合条件的字段或代替整个文档,与db.collection.updateOne()不同的是更新所有符合条件的文档。

语法格式如下:

db.collection.updateMany(
,
,
{

 upsert: <boolean>,
 writeConcern: <document>,
 collation: <document>,
 arrayFilters: [ <filterdocument1>, ... ],
 hint:  <document|string>        

}
)
参数说明:

参考db.collection.update()的参数说明。

使用示例:

// 参考db.collection.update()
回到顶部
删除(Delete Operations)
删除是指对集合当中已存在的文档进行清除操作,MongoDB提供以下几种主要删除文档方法:

db.collection.deleteOne():只删除集合中符合条件的一个文档;
db.collection.deleteMany():删除集合中所有符合条件的文档;
db.collection.remove():删除集合中符合条件的一个或多个文档。
回到顶部
db.collection.deleteOne()
根据filter选项条件删除集合中的单个文档,具体语法格式如下:

db.collection.deleteOne(
,
{

  writeConcern: <document>,
  collation: <document>

}
)
参数说明:

filter:指定基于查询表达式的过滤条件,关于查询表达式可以查看db.collecion.find()中的;
writeConcern:参考db.collection.insert()相同参数说明;
collation:指定校对规则(可选,版本3.4新增);
使用示例:

// 删除指定条件的单个文档
db.orders.deleteOne( { "_id" : 1 } );
{ "acknowledged" : true, "deletedCount" : 1 }
回到顶部
db.collection.deleteMany()
根据filter选项条件删除集合中的单个文档,具体语法格式如下:

db.collection.deleteMany(
,
{

  writeConcern: <document>,
  collation: <document>

}
)
参数说明:

参考db.collection.deleteOne()的参数说明。

使用示例:

// 删除指定条件的多个文档
db.orders.deleteMany( {"cust_id" : "Cam Elot"} );
{ "acknowledged" : true, "deletedCount" : 2 }
注意: 如果是对固定集合进行删除文档操作则会报错,固定集合的清除操作使用方法db.collection.drop()。

回到顶部
总结
本文简单梳理了在Mongo Shell下基本的CRUD操作,主要适用于DBA的运维管理,如果是研发同学,根据不同的编程语言使用不同客户端驱动进行操作,详细同样可以参考官方文档;
针对CRUD各个方面还有其他一些额外的方法,比如查询修改文档方法db.collection.findAndModify(),这里只是总结每个文档操作中一些最基础的方法,对于额外高级的方法这里不再赘述;
掌握了这些基本的CRUD操作,就可以对MongoDB文档进行操作了,但还是需要控制好权限,毕竟数据安全不是小事,做变更之前做好数据的备份,以防万一。
回到顶部
参考
https://docs.mongodb.com/manual/crud/

https://docs.mongodb.com/manual/reference/operator/query-evaluation/

https://docs.mongodb.com/manual/reference/method/db.collection.update/#specify-arrayfilters-for-array-update-operations

https://docs.mongodb.com/manual/reference/method/db.collection.update/#update-with-aggregation-pipeline

☆〖本人水平有限,文中如有错误还请留言批评指正!〗☆

作者: H_Johnny
出处: http://www.cnblogs.com/dbabd/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10051 0
Asp.Net Web API 2第二课——CRUD操作
原文:Asp.Net Web API 2第二课——CRUD操作 Asp.Net Web API 导航     Asp.Net Web API第一课——入门http://www.cnblogs.com/aehyok/p/3432158.html 前言   CRUD代表着 Create、Read、Update、Delete,这是四个基本的数据库操作。
1217 0
C#软件开发实例.私人订制自己的屏幕截图工具(八)添加键盘操作截图的功能
上一篇:C#软件开发实例.私人订制自己的屏幕截图工具(七)添加放大镜的功能 虽然添加了放大镜的功能,但是在进行像素级的定位时,还是不容易精确定位,在用鼠标操作时要改变一两个像素的位置还是有些困难的。
621 0
自己开发一个Java ORM框架(3)-极速CRUD操作
本文目录 1. 新建测试数据库pandaormtest 2. 新建测试Web Project,并导入Panda ORM框架jar包 3. 建立数据库配置文件config.properties 4. 建立实体类 5. 为主键、外键添加注解 6. 直接使用框架中的EntityOperation进行数据库操作测试
25 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13865 0
Apache Flink 零基础入门(四):客户端操作的 5 种模式
本文主要分享 Flink 的 5 种任务提交的方式。熟练掌握各种任务提交方式,有利于提高我们日常的开发和运维效率。
4497 0
DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作
原文:DevExpress ASP.NET 使用经验谈(5)-通过ASPxGridView实现CRUD操作 这节,我们将通过使用DevExpress的ASPxGridView控件,实现对数据的CRUD操作。
1105 0
+关注
幸运码发放
阿里云优惠码阿里云推荐券bieryun.com
171
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载