实验四?MongoDB?文档操作?
【实验目的】:?
1.?掌握?MongoDB?CRUD?基本操作;?
2.?掌握?MongoDB?插入文档?
3.?掌握?MongoDB?更新文档?
4.?掌握?MongoDB?删除文档?
5.?掌握?MongoDB?删除集合。?
【实验内容与要求】:?
MongoDB?是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功?
能最丰富,最像关系数据库的。?
文档的数据结构和?JSON?基本一样。?
所有存储在集合中的数据都是?BSON?格式。?
BSON?是一种类?json?的一种二进制形式的存储格式,简称?Binary?JSON。?
1.使用?find()?方法进行文档基本查询?
语法格式如下:?
db.collection.find(query,projection)?
参数说明:?
query?:可选,使用查询操作符指定查询条件?
projection?:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,?
只需?
省略该参数即可(默认省略)。?
2.文档查询条件的使用?
操作?
格式?
范例?
RDBMS?中的类似语句?
等于?
{<key>:<valu?
e>}?
db.col.find({"by":"x"}?
).pretty()?
where?by?=?'x'?
小于?
{<key>:{$lt:<?
value>}}?
db.col.find({"likes":{?
$lt:50}}).pretty()?
where?likes?<?50?
小于或?
等于?
{<key>:{$lte:?
<value>}}?
db.col.find({"likes":{?
$lte:50}}).pretty()?
where?likes?<=?50?
大于?
{<key>:{$gt:?
<value>}}?
db.col.find({"likes":{?
$gt:50}}).pretty()?
where?likes?>?50?
大于或?
等于?
{<key>:{$gte?
:<value>}}?
db.col.find({"likes":{?
$gte:50}}).pretty()?
where?likes?>=?50?
不等于?
{<key>:{$ne:?
<value>}}?
db.col.find({"likes":{?
$ne:50}}).pretty()?
where?likes?!=?50?
3.特定类型查询?
针对特定类型的文档进行查询,如查询键为?NULL?的空文档?
4.聚合查询
MongoDB?中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后?
的数据结果。db.collection.aggregate()是基于数据处理的聚合管道,每个文档通过一个由多个?
阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列?
的处理,输出相应的结果。?
$sum?
计算总和。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?num_tutorial?:?{$sum?:?
"$likes"}}}])?
$avg?
计算平均值?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?num_tutorial?:?{$avg?:?
"$likes"}}}])?
$min?
获取集合中所有文档?
对应值得最小值。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?num_tutorial?:?{$min?:?
"$likes"}}}])?
$max?
获取集合中所有文档?
对应值得最大值。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?num_tutorial?:?{$max?:?
"$likes"}}}])?
$push?
在结果文档中插入值?
到一个数组中。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?url?:?{$push:?"$url"}}}])?
$addToSet?在结果文档中插入值?
到一个数组中,但不?
创建副本。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?url?:?{$addToSet?:?
"$url"}}}])?
$first?
根据资源文档的排序?
获取第一个文档数?
据。?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?first_url?:?{$first?:?
"$url"}}}])?
$last?
根据资源文档的排序?
获取最后一个文档数?
据?
db.mycol.aggregate([{$group?:?{_id?:?
"$by_user",?last_url?:?{$last?:?"$url"}}}])?
第一部分:?
题目一:插入文档?
MongoDB?使用?insert()?或?save()?方法向集合中插入文档,语法如下:?
db.COLLECTION_NAME.insert(document)《大数据存储与处理》实验指导书?
示例:向数据库?student?的?stuinfo?集合插入以下数据?
//insert?方法插入单个文档?
db.stuinfo.insert({_id:001,name:'alice',age:18})?
//save?方法插入当个文档?
db.stuinfo.save({_id:002,name:'nancy',age:19})?
//插入多个文档?
db.stuinfo.insert([{_id:003,name:'harry',age:18},{_id:004,name:'curry',age:19}])?
文档插入完成后,使用?find()查看集合数据,具体操作步骤如下图所示:?
以上示例中?stuinfo?是我们的集合名,如果该集合不在该数据库中,?MongoDB?会自动?
创建该集合并插入文档。?
还可以可以先将文档定义为一个变量,再进行插入:?
>?s={_id:5,name:'张三',age:19}?
>?db.stuinfo.insert(s)?
操作结果如下图所示:?
题目二:更新文档(区分?update?和?save?的区别)?
MongoDB?使用?update()?和?save()?方法来更新集合中的文档。?
(1)update()?方法用于更新已存在的文档。语法格式如下:?
db.collection.update(<criteria>,<objNew>,upsert,multi,writeConcern)?
参数说明:?
query?:?update?的查询条件,类似?sql?update?查询内?where?后面的。?
objNew?:?
update?的对象和一些更新的操作符(如$,$inc...)等,也可以理解为?sql?update?
查询内?set?后面的?
upsert?:?可选,这个参数的意思是,如果不存在?update?的记录,是否插入?objNew,true?
为插入,默认是?false,不插入。?
multi?:?可选,mongodb?默认是?false,只更新找到的第一条记录,如果这个参数为?true,?
就把按条件查出来多条记录全部更新。?
writeConcern?:可选,抛出异常的级别。?
示例?
通过?update()?方法来更新上述文档的姓名(name):?将姓名(name)为?curry?的文档?更新?
为了?"jack"。?
执行命令:db.stuinfo.update({name:'curry'},{$set:{name:'王五'}})?
通过?find()查看修改是否成功,具体操作步骤如下所示:?
以上语句只会修改第一条发现的文档,如果要修改多条相同的文档,则需要设置?multi?
参数为?true。?
db.stuinfo.update({name:'nancy'},{$set:{name:'王五'}},false,true)?
操作结果如下图所示:
(2)save()?方法通过传入的文档来替换已有文档。语法格式如下:?
db.collection.save(<document>,{writeConcern:<document>})?
参数说明:?
document?:?文档数据。?
writeConcern?:可选,抛出异常的级别。?
示例:替换?_id?为?2?的文档的数据:?
db.stuinfo.save({_id:2,name:'curry',age:20})?
操作步骤如下图所示:?
更多示例:(选做)?
for(var?i=1;i<10;i++)?db.col.insert({count:i,test2:false,test5:true})?
只更新第一条记录:?
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?);?
题目三:删除文档(注意区分?remove?和?delete)?
remove(),deleteOne()?和?deleteMany()?方法可以用来移除集合中的数据。?
(1)删除集合?col?下全部文档?
db.col.deleteMany({})?
或?db.col.remove({})?
具体如下图所示?
?(2)删除指定条件的文档?
删除集合?stuinfo?中?name?等于王五的全部文档:?
db.stuinfo.deleteMany({name:'王五'})?
删除?age?等于?18?的一个文档:?
db.stuinfo.deleteOne({age:18})?
第二部分:?
(1)使用?test?数据库,并新建?items?集合,保存订单相关信息。?
db.createCollection("items")?
(2)插入文档数据:?
每个文档对应订单中某个商品相关信息,包括:?
pnumber:商品编号?
quantity:商品数量?
price:商品单价?
插入如下商品信息:?
db.items.insert([?
{"quantity":2,price:5.0,pnumber:"p003"},?
{quantity:2,price:8.0,pnumber:"p002"},?
{quantity:1,price:4.0,pnumber:"p002"},?
{quantity:2,price:4.0,pnumber:"p001"},?
{"quantity":4,price:10.0,pnumber:"p003"},?
{quantity:10,price:20.0,pnumber:"p001"},?
{quantity:10,price:20.0,pnumber:"p003"},?
{quantity:5,price:10.0,pnumber:"p002"}?
])?
结果:?
(
3)查询插入结果:?
db.items.find().pretty()?:?pretty()?方法以格式化的方式来显示所有文档?
(
4)统计?items?共有多少个文档数据?
db.items.count()?
(
5)查询价格大于?5?的商品数据?
大于使用?gt?操作符,另外操作符前面要带上$符号?
db.items.find({price:{$gt:5}})?
(
6)多条件查询?
例:查询?quantity?为?10?且价格大于等于?5?的商品数据?
db.items.find({quantity:10,price:{$gte:5}})?
(
7)使用?or?来进行条件查询,格式如下:?
db.col.find(?
{?
$or:?
[?
{key1:?value1},?{key2:value2}?
]?
}?
)?
例:查询?quantity?为?10?或价格大于等于?5?的商品数据?
db.items.find({$or:[{quantity:10},{price:{$gte:5}}]})?
(
8)AND?和?OR?联合使用?
例:查询?pnumber?为“p003”且?quantity?为?10?或价格大于等于?5?的商品数据?
db.items.find({pnumber:"p003",$or:[{quantity:10},{price:{$gte:5}}]})?
(
9)使用聚合?aggregate?
例:统计订单中所有商品的数量,即统计?quantity?的总和。?
db.items.aggregate([{$group:{_id:null,total:{$sum:"$quantity"}}}])?
例:通过产品类型来进行分组,然后在统计卖出的数量?
db.items.aggregate([{$group:{_id:"$pnumber",total:{$sum:"$quantity"}}}])?
例:通过相同的产品类型来进行分组,然后查询相同产品类型卖出最多的订单详情。?
db.items.aggregate([{$group:{_id:"$pnumber",max:{$max:"$quantity"}}}])?
例:通过相同的产品类型来进行分组,然后查询每个订单详情相同产品类型卖出的平均?
价格?
db.items.aggregate([{$group:{_id:"$pnumber",price:{$avg:"$price"}}}])?
(10)管道的使用?
例:通过相同的产品类型来进行分组,统计各个产品数量,然后获取最大的数量。?
db.items.aggregate([{$group:{_id:"$pnumber",total:{$sum:"$quantity"}}},{$group:{_id:null?
,max:{$max:"$total"}}}])?
思考题:聚合的作用是什么??
聚合的作用是将不同的文档集合在一起进行分组、筛选、计算和转换等操作,以生成新的文档结果。聚合可以帮助我们对大量数据进行复杂的查询和分析,从而更好地理解和处理数据。
小结?
掌握?MongoDB?CRUD?基本操作;掌握?MongoDB?插入文档;掌握?MongoDB?更新文档;?
掌握?MongoDB?删除文档;掌握?MongoDB?删除集合;掌握?MongoDB?查询文档。
-?MongoDB?CRUD?基本操作涉及插入、读取、更新和删除文档。
-?插入文档可以使用?insertOne()?或?insertMany()?方法,插入一个或多个文档。
-?更新文档可以使用?updateOne()?或?updateMany()?方法,按照指定条件更新一个或多个文档。
-?删除文档可以使用?deleteOne()?或?deleteMany()?方法,删除符合条件的一个或多个文档。
-?删除集合可以使用?drop()?方法,删除整个集合。
-?查询文档可以使用?find()?方法,按照指定条件查询符合条件的文档。可以使用?limit(),?skip(),?sort()?等方法进行限制、跳过和排序。另外,还可以使用聚合操作实现更复杂的查询和分析。