关于MongoDB数据库-增删改查

一、数据库简介

非关系性数据库:

文档document:相当于关系数据库中的一行记录。

集合collection:多个文档组成一个集合,相当于关系数据库中的一张表。

数据库database:多个集合组织构成数据库

为了帮助理解,mongoDB与关系型数据库的对比,如下图:

 

可使用客户端工具NoSQL Manager for MongoDB访问MongoDB数据库。

1、日期格式

Date()

显示当前的时间

new Date()

  构建一个格林尼治时间   可以看到正好和Date()相差8小时,我们是+8时区,也就是时差相差8,所以+8小时就是系统当前时间

ISODate()

  也是格林尼治时间

>  Date()

Wed Jul 22 2020 18:38:50 GMT+0800

>  new Date()

ISODate("2020-07-22T10:42:58.868Z")

>  ISODate()

ISODate("2020-07-22T10:46:26.137Z")

 

db.report_traffic_site_hour.insert({relationid:'aaa',datatime:Date(),innum:300})

{  

"_id" : ObjectId("5f18186f392a971272ac9328"),  

"relationid" : "aaa",

 "datatime" : "Wed Jul 22 2020 18:43:59 GMT+0800",  

"innum" : 300.0

}

 

db.report_traffic_site_hour.insert({relationid:'aaa',datatime:new Date(),innum:200})

{  

"_id" : ObjectId("5f181832392a971272ac9327"),  

"relationid" : "aaa",  

"datatime" : ISODate("2020-07-22T10:42:58.868Z"),  

"innum" : 200.0

}

 

db.report_traffic_site_hour.insert({relationid:'aaa',datatime:ISODate(),innum:100})

{

 "_id" : ObjectId("5f181902392a971272ac9329"),  

"relationid" : "QBGC",  

"datatime" : ISODate("2020-07-22T10:46:26.137Z"),

 "innum" : 100.0

}

 

2、主键 _id

_id 是集合中文档的主键;

_id自动编入索引;

默认情况下,_id 字段的类型为 ObjectID。如果需要,用户还可以将 _id 覆盖为 ObjectID 以外的其他内容。

ObjectID 长度为 12 字节,由几个 2-4 字节的链组成。每个链代表并指定文档身份的具体内容。以下的值构成了完整的 12 字节组合:

一个 4 字节的值,表示自 Unix 纪元以来的秒数

一个 3 字节的机器标识符

一个 2 字节的进程 ID

一个 3 字节的计数器,以随机值开始

通常,你不必担心要如何生成 ObjectID。如果文档尚未分配 _id 值,MongoDB 将自动生成一个 _id 值;

_id 字段基本上是不可变的。在创建文档之后,根据定义,它已被分配了一个无法更改的 _id。话虽如此,在插入新文档时是可以覆盖 _id 的。

 

二、NoSQL Manager for MongoDB工具页面简介 

注:可参考https://www.pianshen.com/article/532179412/     NoSQL Manager for MongoDB 使用简单教程

以查询为例进行介绍:

模拟数据如下

1shell面板命令查询

首先选中数据表,打开shell面板。

 shell面板中输入:

db.ceshi.find({id:"b",time:{$gte:"3"}},{_id:0}).limit(100).skip(0).sort({time:1})

查询结果如下:

#上面方法为查询id="b"time大于等于3_id字段设置不显示(0不显示,1显示),限制100条,跳过前面的0条(skip),按time排序(1升序,0倒叙)    

# 字段不用加引号

 2通过GUI来查询

 

三、常用操作

增、删、改、查

注:可参考

https://www.cnblogs.com/jmcui/p/8858111.html

https://www.cnblogs.com/ywjfx/p/10129007.html

1增加

语法: db.collectionName.insert(document)

①不指定id,数据库会随机分配一个id

db.report_traffic_site_hour.insert({relationid:'aaa',datatime:ISODate('2020-07-14T09:00:00Z'),innum:8000});

②指定id

db.report_traffic_site_hour.insert({_id:'aaa#2020-07-14 18:00',relationid:'QBGC',datatime:ISODate('2020-07-14T10:00:00Z'),innum:2000})

③添加一个document

db.user.insert({_id:6,name:'zhaos',age:23,sex:'f'});

④添加多个document

db.user.insert({_id:7,name:'zhaos',age:23,sex:'f'},{_id:8,name:zpl,age:23,sex:'f'});

 2删除

语法: db.collection.remove(查询表达式选项)

选项是指需要删除的文档数,{0/1},默认是0,删除全部文档。

1

db.report_traffic_site_hour.remove({relationid:'aaa',datatime:ISODate('2020-07-14T09:00:00Z')});

2

#只删除一个gender:'m's文档,num是指删除的文档数

db.user.remove({gender:'m',1})

 3、修改

语法:

Update()方法

db.collection.update(

   <query>,

   <update>,

   {

     upsert: <boolean>,

     multi: <boolean>,

     writeConcern: <document>

   })

参数说明:

Query:查询条件

Update:更新语句

Upsert:可选,默认值是false。如果根据查询条件没找到对应的文档,如果设置为true,相当于执行insert,如果设置为false,不做任何的操作。

Multi:可选,默认false,只更新找到的第一条记录,如果为true,把查出来的多条记录全部更新

writeConcern:可选,跑出异常的级别

 $inc 自增

$mul 

$rename 重命名

$setOnInsert  

$set 用来指定一个键的值,如果不存在则创建它

$unset 用来指定一个键的值,如果不存在不创建创建它

$min 最小

$max 最大

$currentDate 当前时间

 1

db.report_traffic_site_hour.update({relationid:'aaa',datatime:ISODate('2018-07-14T10:00:00Z')},{$set:{innum:5000}})

结果:WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

 2

db.report_traffic_site_hour.update({relationid:'aaa',datatime:ISODate('2018-07-14T10:00:00Z')},{$inc:{innum:1000}})

结果:WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

 4、查询

语法: db.collection.find(查询表达式,查询的列)

1

#查询所有文档

db.report_traffic_site_hour.find() 

db.report_traffic_site_hour.find({relationid:'aaa'})

 2

#查询QBGC_id不显示,relationid,datatime,innum三列显示,0表示显示不显示该列,1表示显示该列

db.report_traffic_site_hour.find({relationid:'aaa'},{_id:0,relationid:1,datatime:1,innum:1})

 $ne  不等于   db.user.find({age:{$ne:30}})

$gt  大于     db.user.find({age:{$gt:30}})

$gte 大于等于 db.user.find({age:{$gte:30}})

$lt  小于     db.user.find({age:{$lt:30}})

$lte 小于等于 db.user.find({age:{$lt:30}})

$in         db.user.find({age:{$in:[28,29,30]}})

$nin 不在     db.user.find({age:{$nin:[28,29,30]}})

$mod   : {field:{$mod:[ divisor(除数), remainder(余数)]}}

db.report_traffic_site_hour.find({innum:{$mod:[10,5]}})

$exists     语法:{field:{$exists:1}}

db.user.find({age:{$exists:1}})   查询有age列的文档

 $where   条件   

查询innum 大于1000小于5000的文档

db.report_traffic_site_hour.find({$where:'this.innum>1000'  && 'this.innum<5000'})

db.report_traffic_site_hour.find({relationid:'aaa',$where:'this.innum>1000'  && 'this.innum<5000'})    

db.report_traffic_site_hour.find({relationid:'aaa',$where:'this.innum<1000'  || 'this.innum>5000'})    

 

加法:$add   如:{$add:['$innum','$outnum']}
减法:$subtract
乘法:$multiply
除法:$divide

 

 5、聚合函数

 使用聚合框架可以对集合中的文档进行变换和组合。基本上,可以用多个构件创建一个管道(pipeline),用于对一连串的文档进行处理。这些构件包括筛选(filtering)、投射(projecting)、分组(grouping)、排序(sorting)、限制(limiting)和跳过(skipping)。

例:

db.driverLocation.aggregate(    

{$match:{areaCode:'350203'}},    

{$project:{driverUuid:1,uploadTime:1,positionType:1}},    {$group:{_id:{driverUuid:'$driverUuid',positionType:'$positionType'},uploadTime:{$first:{$year:'$uploadTime'}},count:{'$sum':1}}},    

{$sort:{count:-1}},    

{$limit:100},    

{$skip:50}

)

 ① 筛选(filtering)—> $match

一般放在第一个,可快速将不需要的文档过滤掉,$match可以使用所有常规的查询操作符("$gt""$lt""$in"等)

 ② 投射(projecting)—> $project

可以通过指定 {"fieldname" : 1} 选择需要投射的字段,或者通过指定 { "fieldname":0 } 排除不需要的字段;

还可对字段起别名:db.users.aggregate({"$project" : {"userId":"$_id", "_id":0}})

 ③ 分组(grouping)—> $group

选定了需要进行分组的字段,就可以将选定的字段传递给"$group"函数的"_id"字段{$group:{_id:null,sum:{$sum:"$innum"}}}

如上,_id:null是没有分组字段,直接求innum字段的sum和,"$innum"是引用该字段,注意要加单引号或双引号

 ④ 限制(limiting)—> $limit

{$limit:100}返回结果集的前100个文档

 ⑤ 跳过(skipping)—> $skip

{$skip:50}跳过结果集的前50个文档

 注意:$limit$skip的顺序,如下

{$limit:100},{$skip:50}  返回结果集的前100个,然后在此基础上再跳过这100个的前50个,最后返回的是50个文档

{$skip:50},{$limit:100} 先跳过结果集的前50个,然后在此基础上再限制100个,最后返回的是100个文档

拆分(unwind)—> $unwind

可以将数组中的每一个值拆分为单独的文档。

例如文档:{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }

   聚合运算:db.inventory.aggregate( [ { $unwind : "$sizes" } ] )

   结果:

{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }

 

 1分组操作符:

{$sum : value}  对于分组中的每一个文档,将value与计算结果相加。

{$avg : value} 返回每个分组的平均值

{$max : expr} 返回分组内的最大值。

{$min : expr} 返回分组内的最小值。

{$first : expr} 返回分组的第一个值,忽略后面所有值。只有排序之后,明确知道数据顺序时这个操作才有意义。

{$last : expr} "$first"相反,返回分组的最后一个值。

字符串表达式:

适用于单个文档的运算

{$substr : [expr, startOffset, numToReturn]} 其中第一个参数expr必须是个字符串,这个操作会截取这个字符串的子串(从第startOffset字节开始的numToReturn字节,注意,是字节,不是字符。在多字节编码中尤其要注意这一点)expr必须是字符串。

{$concat : [expr1, expr2, ..., exprN]]} 将给定的表达式(或者字符串)连接在一起作为返回结果。

{$toLower : expr} 参数expr必须是个字符串值,这个操作返回expr的小写形式。

{$toUpper : expr} 参数expr必须是个字符串值,这个操作返回expr的大写形式。

 

 2、逻辑操作符 $or, $and, $nor, $not

$or  

语法:{$or: [ {<expression1>}, {<expression2>}, ... , {<expressionN>} ] }

db.report_traffic_site_hour.find({$or:[{relationid:'bbb'},{relationid:'ccc'},{relationid:'aaa'}]})

类似:db.report_traffic_site_hour.find({relationid:{$in:['bbb','ccc','aaa']}})

注意$or$in 的区别,$or后面是两个或两个以上表达式,$in后面是数组;

 $and

语法:{$and: [ {<expression1>}, {<expression2>}, ... , {<expressionN>} ] }

 db.report_traffic_site_hour.find({$or:[{relationid:'bbb'},{innum:

5000}]})

db.inventory.find({$and:[{ price:{$ne:1.99}},{price: {$exists: true}}]})

 $nor  都不是

语法:{$nor: [ {<expression1>}, {<expression2>}, ... , {<expressionN>} ] }

db.report_traffic_site_hour.find({$nor:[{relationid:'bbb'},{relationid:'ccc'},{relationid:'aaa'}]})

 $not  

语法: { field: { $not: {<operator-expression>} } }

db.inventory.find({price:{$not:{$gt:1.99}}})

 

 3、日期表达式

$ifNull 如果为空

{$ifNull : [expr, replacementExpr]} 如果exprnull,返回replacementExpr,否则返回expr

日期表达式

适用于单个文档的运算

{$year: "$date" } 返回日期的年份部分

{$month: "$date" } 返回日期的月份部分

{$dayOfMonth: "$date" } 返回日期的天部分

{$hour: "$date" } 返回日期的小时部分

{$minute: "$date" } 返回日期的分钟部分

{$second: "$date" } 返回日期的秒部分

{$millisecond: "$date" } 返回日期的毫秒部分

{$dayOfYear: "$date" } 一年中的第几天

{$dayOfWeek: "$date" } 一周中的第几天,between 1 (Sunday) and 7 (Saturday).

{$week: "$date" } 053之间的数字返回一年中日期的周数。周从星期日开始,第一周从一年中的第一个星期天开始。一年中第一个星期日之前的日子是在第0周。

posted @ 2021-01-26 11:02  紫蕈  阅读(101)  评论(0编辑  收藏  举报