• 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}}}
    ])

     

  • 相关阅读:
    [LeetCode 116 117]
    看几道JQuery试题后总结(下篇)
    插入排序及其扩展
    Operation not permitted引发的惊魂72小时
    dddd
    天底下什么人都有,不要跟他们一般见识就是了
    qt宽字符串中文乱码(codec->toUnicode值得学习)
    qt事件传递过程和处理
    qt新进程工作目录的设置(工作目录确实是被子进程继承的,但也可以设置)
    面试都爱问的委托和事件(纠正)
  • 原文地址:https://www.cnblogs.com/Lvkang/p/14355612.html
Copyright © 2020-2023  润新知