本章节我们将向大家介绍如何对 MongoDB 集合中的文档进行 CRUD 操作。MongoDB 文档的数据结构和 JSON 基本一样,所有存储在集合中的数据都是 BSON 格式。BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,在 MongoDB 3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany() 方法。
语法格式:
db.COLLECTION_NAME.insert(document)
示例:
# 插入一条到 col 集合 test> db.col.insert({name:"insert"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6e2fd10366fa87109a123") } } # 重复插入一条数据到 col 集合 # MongoDB 插入的数据会自动创建一个 _id 字段,该字段是唯一的,相当于主键 test> db.col.insert({_id:ObjectId("64e6e2fd10366fa87109a123"), name:"insert"}) Uncaught: MongoBulkWriteError: E11000 duplicate key error collection: test.col index: _id_ dup key: { _id: ObjectId('64e6e2fd10366fa87109a123') } ... # 查看 col 集合数据 test> db.col.find() [ { _id: ObjectId("64e6e2fd10366fa87109a123"), name: 'insert' }, { _id: '64e6e2fd10366fa87109a123', name: 'insert' } ]
注意:若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
我们也可以将数据定义为一个变量,如下所示:
test> doc=({title: 'MongoDB 教程', url: 'https://www.hxstrive.com' }) { title: 'MongoDB 教程', url: 'https://www.hxstrive.com' }
执行插入操作:
test> db.col.insert(doc) { acknowledged: true, insertedIds: { '0': ObjectId("64e6e17f10366fa87109a11f") } }
插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
语法格式:
db.collection.save( <document>, { writeConcern: <document> } )
参数说明:
• document:文档数据。
• writeConcern:可选,抛出异常的级别。
示例:
# 方法已废弃了 test> db.col.save({name:"hello world", type:"msg"}) TypeError: db.col.save is not a function
注意:如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法在新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。
insertOne() 用于向集合插入一个新文档,语法格式:
db.collection.insertOne( <document>, { writeConcern: <document> } )
参数说明:
document:要写入的文档。
writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
示例:
# 插入单条数据 test> db.col2.insertOne({name:"插入一条"}) { acknowledged: true, insertedId: ObjectId("64e6e22e10366fa87109a120") } # 查看插入的数据 test> db.col2.find() [ { _id: ObjectId("64e6e22e10366fa87109a120"), name: '插入一条' } ]
db.collection.insertMany() 用于向集合插入一个多个文档,语法格式:
db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
参数说明:
document:要写入的文档。
writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
ordered:指定是否按顺序写入,默认 true,按顺序写入。
示例:
# 插入多条数据 test> db.col3.insertMany([{name:"插入多条1"}, {name:"插入多条2"}]) { acknowledged: true, insertedIds: { '0': ObjectId("64e6e25710366fa87109a121"), '1': ObjectId("64e6e25710366fa87109a122") } } # 查看插入的数据 test> db.col3.find() [ { _id: ObjectId("64e6e25710366fa87109a121"), name: '插入多条1' }, { _id: ObjectId("64e6e25710366fa87109a122"), name: '插入多条2' } ]
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } )
参数说明:
query:update 的查询条件,类似 sql update 查询内 where 后面的。
update:update 的对象和一些更新的操作符(如 $, $inc...)等,也可以理解为 sql update 查询内 set 后面的
upsert:可选,这个参数的意思是,如果不存在 update 的记录,是否插入 objNew, true 为插入,默认是 false,不插入。
multi:可选,mongodb 默认是 false, 只更新找到的第一条记录,如果这个参数为 true, 就把按条件查出来多条记录全部更新。
writeConcern:可选,抛出异常的级别。
示例:
# 插入一条数据到 col 集合 test> db.col.insert({name:"hello world", type:"msg"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6e73010366fa87109a124") } } # 如果 type="msg",则将 name 更新为 “hello mongodb” test> db.col.update({type:"msg"}, {$set:{name:"hello mongodb"}}) { acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 } # 查询 col 集合数据 test> db.col.find() [ { _id: ObjectId("64e6e73010366fa87109a124"), name: 'hello mongodb', type: 'msg' } ]
以上的 update 语句只会修改第一条匹配的文档,如果你要修改多条匹配的文档,则需要设置 multi 参数为 true。如:
test> db.col.update({type:"msg"}, {$set:{name:"hello mongodb"},{multi:true})
下面是更多关于 update 的实例:
# 只更新第一条记录 db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); # 全部更新 db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} }, false, true ); # 只添加第一条 db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} }, true, false ); # 全部添加进去 db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} }, true, true ); # 全部更新 db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} }, false, true ); # 只更新第一条记录 db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} }, false, false );
MongoDB 使用 remove() 函数移除集合中的数据,在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。
remove() 方法的基本语法格式如下所示:
db.collection.remove( <query>, <justOne> )
如果你的 MongoDB 是 2.6 版本以后的,语法格式如下:
db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document> } )
参数说明:
query:(可选)删除的文档的条件。
justOne: (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
writeConcern:(可选)抛出异常的级别。
示例:
# 准备数据,插入三个文档到 col 集合 test> db.col.insert({name:"mongo", type:"mongodb"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6eaad10366fa87109a125") } } test> db.col.insert({name:"mongod", type:"mongodb"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6eab010366fa87109a126") } } test> db.col.insert({name:"mongos", type:"mongodb"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6eab310366fa87109a127") } } # 查看 col 集合中的数据 test> db.col.find() [ { _id: ObjectId("64e6eaad10366fa87109a125"), name: 'mongo', type: 'mongodb' }, { _id: ObjectId("64e6eab010366fa87109a126"), name: 'mongod', type: 'mongodb' }, { _id: ObjectId("64e6eab310366fa87109a127"), name: 'mongos', type: 'mongodb' } ] # 删除 type 为 mongodb 的文档 test> db.col.remove({type:"mongodb"}) DeprecationWarning: Collection.remove() is deprecated. Use deleteOne, deleteMany, findOneAndDelete, or bulkWrite. { acknowledged: true, deletedCount: 3 } # 查看集合数据,已经是空集合 test> db.col.find()
如果你只想删除第一条找到的记录可以设置 justOne 为 1,如下所示:
db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
如果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):
db.col.remove({})
注意:remove() 虽然继续可以使用,但是已经过时了,官方推荐使用 deleteOne() 和 deleteMany() 方法。例如:
# 如删除集合下全部文档: db.inventory.deleteMany({}) # 删除 status 等于 A 的全部文档: db.inventory.deleteMany({ status : "A" }) # 删除 status 等于 D 的第一个文档: db.inventory.deleteOne( { status: "D" } )
MongoDB 查询文档使用 find() 方法,find() 方法以非结构化的方式来显示所有文档。
MongoDB 查询数据的语法格式如下:
db.collection.find(query, projection)
参数说明:
query:可选,使用查询操作符指定查询条件。
projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
>db.col.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
示例:
# 准备一条数据 test> db.col.insert({name:"mongo", type:"mongodb"}) { acknowledged: true, insertedIds: { '0': ObjectId("64e6ed5410366fa87109a128") } } # 查看数据 test> db.col.find().pretty() [ { _id: ObjectId("64e6ed5410366fa87109a128"), name: 'mongo', type: 'mongodb' } ]
注意:除了 find() 方法之外,还有一个 findOne() 方法。但是,MongoDB 推出的 MongoDB Shell 查询自动就进行格式化了。
如果你熟悉常规的 SQL 语句,通过下表可以更好的理解 MongoDB 的条件语句查询:
MongoDB 的 find() 方法可以传入多个键 (key),每个键 (key) 以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
db.col.find({ key1:value1, key2:value2 })
示例
# 准备点数据 test> db.col.insert({name:"mongo", type:"mongodb"}) test> db.col.insert({name:"mongos", type:"mongodb"}) test> db.col.insert({name:"mongod", type:"mongodb"}) test> db.col.insert({name:"shell", type:"mongodb"}) # 查询 type 为 mongodb 且 name 为 mongo 的数据 test> db.col.find({type:"mongodb",name:"mongo"}) [ { _id: ObjectId("64e6ed5410366fa87109a128"), name: 'mongo', type: 'mongodb' } ]
以上示例类似 WHERE 语句:WHERE type='mongodb' AND name='mongo'
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
db.col.find( { $or: [ {key1: value1}, {key2:value2} ] } )
示例
# 准备点数据 test> db.col.insert({name:"mongo", type:"mongodb"}) test> db.col.insert({name:"mongos", type:"mongodb"}) test> db.col.insert({name:"mongod", type:"mongodb"}) test> db.col.insert({name:"shell", type:"mongodb"}) # 查询 name 为 mongod 或 mongos 的文档 test> db.col.find({$or:[{name:"mongod"}, {name:"mongos"}]}) [ { _id: ObjectId("64e6ee6310366fa87109a129"), name: 'mongos', type: 'mongodb' }, { _id: ObjectId("64e6ee6710366fa87109a12a"), name: 'mongod', type: 'mongodb' } ]
以上示例类似 WHERE 语句:WHERE name='mongod' AND name='mongos'
以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为:
where type='mongodb' AND (name='mongod' AND name='mongos')
示例:
# 准备点数据 test> db.col.insert({name:"mongo", type:"mongodb"}) test> db.col.insert({name:"mongos", type:"mongodb"}) test> db.col.insert({name:"mongod", type:"mongodb"}) test> db.col.insert({name:"shell", type:"mongodb"}) # 查询 type 为 mongodb,且 name 为 mongod 或 mongos 的文档 test> db.col.find({type:"mongodb", $or:[{name:"mongod"}, {name:"mongos"}]}) [ { _id: ObjectId("64e6ee6310366fa87109a129"), name: 'mongos', type: 'mongodb' }, { _id: ObjectId("64e6ee6710366fa87109a12a"), name: 'mongod', type: 'mongodb' } ]