MongoDB知识整理

一 简介

MongoDB属于NoSQL是非关系型数据库。

关系型数据库采用的结构化的数据,NoSQL采用的是键值对的方式存储数据。 

1.2MySQL与MongoDB之间最基本的差别是什么?

MySQL和MongoDB两者都是免费开源的数据库。MySQL和MongoDB有许多基本差别包括数据的表示(data representation),查询,关系,事务,schema的设计和定义,标准化(normalization),速度和性能。 

1.3MongoDB的优势有哪些

面向文档的存储:以 JSON 格式的文档保存数据。

架构简单

没有复杂的连接

深度查询能力,MongoDB支持动态查询。

容易调试

容易扩展

不需要转化/映射应用对象到数据库对象

使用内部内存作为存储工作区,以便更快的存取数据。

1.4mongodb和关系型数据库术语对比

1.5MongoDB支持哪些数据类型

String、Integer、Double、Boolean、Object、Object ID、Arrays、Min/Max Keys、Datetime、Code、Regular Expression等。 

二基本语法

2.1插入索引、查看索引、删除索引

创建一个索引

db.collection.createIndex(keys, options)

语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可db.col.createIndex({"title":1})

db.col.createIndex({"title":1,"description":-1})

查看集合索引

db.col.getIndexes()

查看集合索引大小

db.col.totalIndexSize()

删除集合所有索引

db.col.dropIndexes()

删除集合指定索引

db.col.dropIndex("索引名称") 

2.2插入insert

插入单条数据

db.col.insert({name:"java",age:"保密",author:null})

插入带数组的数据

db.col.insert({name:".net",age:88,author: ["xiaoxu","xiaozhang","xiaoliu"]})

插入多条数据

db.col.insert([{name:"序员修炼之旅",age:2,from: "CTU"},

{name: "mongdo",age:13,from: "USA"},

{name: "C++",from: "USA" ,author:["xiaoxu","xiaozhang"]}])

2.3更新update

db.collectionName.update({key:value},{$set:{newkey:newValue}})

如db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})

2.4删除delete

db.collectionName.remove({key:value})

如db.col.remove({'title':'MongoDB 教程'})

2.5查找find

语法格式

db.collection.find(query, projection)

$and

db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"})

$or

db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]})

db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]})

大于小于

db.posts.find( { qty: { $gt: 50 ,$lt: 80}} )

$lt小于

db.col.find({"likes":{$lt:50}})

$lte小于等于

db.col.find({"likes":{$lte:50}})

$gt大于

db.col.find({"likes":{$gt:50}})

$gte大于等于

db.col.find({"likes":{$gte:50}})

$ne不等于

db.col.find({"likes":{$ne:50}})

2.6子文档操作

db.getCollection("ProjectInfo").find({FormValues:{$elemMatch:{value:"0011"}}})

查询ProjectNumber":"0011"和子文档里FormValues.key的值为"1536130777269",修改FormValues.$.value的值为"0011"

db.getCollection("ProjectInfo").update(

{"ProjectNumber":"0011","FormValues.key": "1536130777269"},

{$set:{"FormValues.$.value":"0011"}}

); 

2.7关于null的查询

查询集合c中y的值为null或者不存在

>db.col.find( { “y” : null } )

 

查询集合c中y的值为null,(仅返回y的值为null的数据,不会返回不存在的)

>db.col.find( { “y” : { $type : 10 } } )

还有一种写法如下

>db.col.find({“y”:{“$in”:[null], “$exists”:true}})

 

查询集合c中y的值不存在(不会返回y的值为null的数据)

>db.col.find( { “y” : { $exists : false } } )

 

查询集合c中y的值不为null且存在的记录

>db.col.find( { “y” : {"$ne":null, $exists: true }} )

或者:>db.col.find( { “y” : {"$ne":null }} )

 

三聚合语法

3.1阶段操作符

$project

修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。

只查询ProjectState属性 1为显示 0为不显示 _id默认显示

db.getCollection("PI_ProjectInfo").aggregate({$project:{ProjectState:1,_id:0}});

只显示ProjectState:1集合的ProjectState属性

db.getCollection("PI_ProjectInfo").aggregate({$match:{ProjectState:1}},{$project:{ProjectState:1,_id:0}}); 

$match

用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。

查询ProjectName是"0011"的集合

db.getCollection("PI_ProjectInfo").aggregate({$match:{ProjectName:"0011"}});

查询ProjectState>1的集合

db.getCollection("PI_ProjectInfo").aggregate({$match:{ProjectState:{$gt:1}}});

当 match 条件和 group 同时存在时,顺序会影响检索结果,必须先写 match 在前面。 

$limit

用来限制MongoDB聚合管道返回的文档数。

db.getCollection("PI_ProjectInfo").find().limit(5)

或者

db.getCollection("PI_ProjectInfo").aggregate({$match:{ProjectState:1}},

{$project:{_id:1}},

{$sort:{_id:1}},

{$limit:5}

); 

$skip

在聚合管道中跳过指定数量的文档,并返回余下的文档。

分页,跳过1条取3条

db.collection.find(查询条件).sort(排序方式).skip((页码-1)*每页数据条数).limit(每页数据条数)

db.getCollection("PI_ProjectInfo").find().limit(3).skip(1)

查询ProjectState为1并以id分页的第二页数据的id

db.getCollection("PI_ProjectInfo").aggregate({$match:{ProjectState:1}},

{$sort:{_id:1}},

{$skip:1},{$limit:2},

{$project:{_id:1}},

); 

$unwind

将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

查询子文档里FormValues.value的值为"0011",显示ProjectNumber和嵌套文档FormValues

db.getCollection("PI_ProjectInfo").aggregate({$unwind:{path:"$FormValues"}},{$match:{"FormValues.value":"0011"}},

{$project:{"ProjectNumber":1,"FormValues":1,_id:0}});

 结果

// 1

{

"ProjectNumber": "0011",

"FormValues": {

"key": "ProjectName",

"value": "0011"

}

}

 

// 2

{

"ProjectNumber": "0011",

"FormValues": {

"key": "ProjectNumber",

"value": "0011"

}

} 

 

$group

将集合中的文档分组,可用于统计结果。

_id值必须的,分组依据,在分组中可以使用$sum,$avg等子聚合操作

以ProjectState分组统计数量

db.getCollection("ProjectInfo").aggregate(

{$group:{_id:"$ProjectState",count:{$sum:1}}}

);

统计MemberType列数值总和

db.test.aggregate({$group:{_id:null,a:{$sum:"$MemberType"}}})

$sort:将输入文档排序后输出。

以CreateDate正序并且以_id倒序查询,1为正序 -1 为倒序

db.getCollection("ProjectInfo").aggregate({$sort:{CreateDate:1,_id:-1}});

查询ProjectState为1集合的id属性,并与id属性倒序

db.getCollection("ProjectInfo").aggregate({$match:{ProjectState:1}},

{$project:{_id:1}},

{$sort:{_id:1}});

 

$geoNear

输出接近某一地理位置的有序文档。

 

$count

统计操作符,用于统计文档的数量

db.getCollection("PI_ProjectInfo").aggregate(

{$match:{ProjectState:1}},

{$count:"count"},

);

 

$lookup

连接操作符,用于连接同一个数据库中另一个集合,并获取指定文档

$lookup:{ from:<要连接的表>, localField:<当前表的属性>, foreignField:<连接表的属性> as:<新的数组属性> }}

连表查询签字确认和签字确认成员表 db.getCollection('DC_ApprovalSignature').aggregate({

 

$lookup:{

from:"DC_ApprovalMember",

localField:"_id",

foreignField:"ASId",

as:"DC_ApprovalMember"

}

 

},{$unwind:"$DC_ApprovalMember"})

 

db.getCollection('ApprovalSignature').aggregate(

{$lookup:{

from:"ApprovalMember",

localField:"_id",

foreignField:"ASId",

as:"ApprovalMember"

}

})

 

$AddFields

向文档中添加新字段,输出包含来自输入文档和新添加字段的所有现有字段文档

{$addFields:{<newField>:<expression>,...}}

查询时添加一列(子文档中UserOrder的和) db.getCollection('DC_ProjectInformation').aggregate({$addFields:{subUserOrder:{$sum:"$ProjectMembers.UserOrder"}}})

只查询添加的一列(子文档中UserOrder之和) db.getCollection('DC_ProjectInformation').aggregate({$addFields:{subUserOrder:{$sum:"$ProjectMembers.UserOrder"}}},{$project:{subUserOrder:1,_id:0}})

向嵌入文档中添加一列 newFiled db.getCollection('DC_ProjectInformation').aggregate({$addFields:{"ProjectMembers.newFiled":"newFiled"}})

 $facet

将两个不同的聚合函数放在一起,进行结果展示

db.getCollection("222-LogSiteStatistics-2020").aggregate([
{$facet:{
"最快100":[
{$sort:{"FastestMilliseconds": 1}},
{$project:{_id:0,SiteName:1,FastestMilliseconds:1,FastestAPIAddress:1}},
{$limit:10}
],
"最慢100":[
{$sort:{"SlowestMilliseconds": -1}},
{$project:{_id:0,SiteName:1,SlowestMilliseconds:1,SlowestAPIAddress:1}},
{$limit:10}
]
}}
])

 

3.2表达式操作符

$and 表达式全部为true 返回true ,否则false

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

 

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

 

$eq 比较两个值返回true或false {$eq:[<expression1>,<expression2>]}

 

$ifNull 计算表达式,如果表达式计算为非null,则返回表达式值,如果表达式为null(包括未定义或缺少字段),则返回替换表达式的值

 

$cond 计算Boolean表达式以返回指定的返回表达式之一

{$cond:[<boolean-expression>,<true-case>,<false-case>]}

获取表中ApprivakState属性,1则输出true,其它输出false

db.getCollection('DC_ApprovalSignature').aggregate({ $project:{_id:1,ApprovalState:{$cond:{if:{$eq:["$ApprovalState",1]},then:"true",else:"false"}}}})

 

$in 返回一个boolean值,指示指定数值是否在数组中

db.user.find({from: {$in:[ "CTU","USA"]}})

 

$not 计算布尔值 ,返回相反的布尔数值

 

累加器

$sum,$avg,$first,$last,$max,$min

只能在$group和$project中使用

如果在包含数字和非数字值的字段上使用,则 $sum忽略非数字值并返回数字总和。如果用于集合中任何文档中都不存在的字段,则 $sum返回0该字段。如果所有操作数均为非数字,则$sum返回0。

3.3一些特殊的用法

分组 TopN的写法

通过调整$slice里的值来获取topN的数据。
如果想分组显示,则去掉$unwind和$replaceRoot语句即可。
db.getCollection("LogSiteStatistics").aggregate([
{$sort: {FastestMilliseconds: 1} },
{$group: {_id: '$SiteName',records: {$push: '$$ROOT'}}},
{$project: {_id: 0,SiteName: "$_id",
records: {$slice: ['$records',1]} },
},
{
"$unwind": "$records"
},
{
"$replaceRoot": {
"newRoot": "$records"
},
}
]);

对某一列的sum

db.getCollection("LogSiteStatistics").aggregate([
{"$match":{"SiteName":"开发WebAPI"}},
{"$group":{_id:"$SiteName",sumFaceAmnt:{"$sum":"$Frequency"}}},
//{$match:{sumFaceAmnt:{$lt:100}}}
])

 

原文地址:https://www.cnblogs.com/Lvkang/p/14355612.html