什么是MongoDB

基于分布式文件存储的数据库,介于非关系型和关系型数据库之间。

MongoDB和MySQL对比

MongoDB有什么特点

(1)面向集合存储数据,数据以json格式存储;

(2)查询功能强大,几乎可以实现所有关系型数据库的单表查询功能;

(3)自带分布式文件系统,方便集群部署;

(4)自带了对map-reduce运算框架的支持。

MongoDB为什么快

(1)没有事务约束;

(2)使用的内存映射技术 ,写入数据时候只要在内存里完成就可以返回给应用程序,写入磁盘是异步操作;热点数据放入内存;数据在磁盘中相对集中,减少随机读写耗费的磁头定位时间;

(3)没有join,不使用关系。没有关系的存在,就表示每个数据都好比是拥有一个单独的存储空间,然后一个聚集索引来指向。

MongoDB适用场景

(1)网站实时数据处理,如PV、UV、统计商品的收藏次数、加入购物车次数、曝光次数等。

(2)服务器日志记录;

(3)大数据量,TB甚至PB级别的数据存储;

(4)数据模型经常变化,需要支持水平扩展

(5)游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新

物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。

社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能

物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析

视频直播,使用 MongoDB 存储用户信息、礼物信息等。

MongoDB不适用场景

(1)数据修改需要严格的事物控制;

(2)功能的业务关系复杂、涉及到多表关联;

(3)比较重要的业务数据,如订单、商品、用户等数据。

MongoDB集合

MongoDB的集合,可类比于MySQL的表,字段(field)可类比于MySQL的列(column)。区别是,集合的filed是可动态扩展的,并且数据类型没有限制,不像Mysql需要先定义列名、列的字段类型等。

此外,集合无需像mysql的表一样事先定义。使用db.collectionName.insert()语句,插入一条json数据,该集合便生成了。

集合由文档组成,每个文档就是一条json数据。

插入文档

向集合中插入一个文档(类比向表中插入一条数据):

 `db.getCollection("b2b_theme_activity").insert( {   "merchant_code": "1ed0528595197975fa72f5ec8f9e0c62",  "dfx_type": NumberInt("1"),  "create_time": ISODate("2020-03-16T22:36:01.964Z"),  "member_code": "e69e61a77b1ccc7b90be7995c6a6021f",  "user_name": "李郃",  "merchant_name": "南京好享家智能家居有限公司",  source: NumberInt("10"),  "visit_duration": "",  type: NumberInt("11"),  "member_name": "测试企业开户01",  "theme_activity_page_title": "测试test01",  "login_name": "17366180925",  "user_id": "1161150535707852801",  event: NumberInt("20"),  "theme_activity_id": "1238383672212533250"} );  复制代码

修改文档

语法

修改文档的语法是:

db.collection.update(  ,  ,  {   upsert: ,   multi: ,   writeConcern:   })复制代码
  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如,,,inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。

例子

现有集合:t_test_log,希望修改requestUri为:/ops/api/b2b/theme-activities的文档的requestSource值为1,且只修改符合条件的第一条数据,脚本如下:

db.t_test_log.update({'requestUri':'/ops/api/b2b/theme-activities'},{$set:{'requestSource': '1'}})复制代码

如果想把所有符合条件的文档数据都修改了,则加上:{multi:true}

db.t_test_log.update({'requestUri':'/ops/api/b2b/theme-activities'},{$set:{'requestSource': '2'}}, {multi:true})复制代码

删除文档

语法

db.collection.remove(   ,   )复制代码
  • query:查询
  • justOne:是否只删除符合条件的第一个文档,true:是,false:否 默认false

例子

删除符合条件的第一个文档:

db.t_test_log.remove({'requestUri':'/ops/api/b2b/theme-activities/11111/22222/testPut'},1)复制代码

删除符合条件的所有文档:

db.t_test_log.remove({'requestUri':'/ops/api/b2b/theme-activities/11111/22222/testPut'})复制代码

查询

简单查询

select * from  spu where  spu_name="test0123"db.spu.find({ spu_name:"test0123" })复制代码

and

select * from  spu where  spu_name="test0123" and  type=3db.spu.find({spu_name:"test0123", type:"3" });复制代码

like

select * from  user where  username like "%test0123%"db.user.find({username:/test0123/});复制代码

大于等于、小于等于

//大于、大于等于、小于、小于等于 $lt, $lte, $gt, $gteselect * from  user where  age>=10 and age<=20db.user.find({ age:{$gte:10, $lte:20} });复制代码

等于null

select * from  user where  address is nulldb.user.find({ address: null });复制代码

不为null

select * from  user where  address is not nulldb.user.find({ address: {$ne:null} });复制代码

不为null 且不为""

select * from  user where  address is not null and address !=''db.user.find({ address: {$nin:[null,"" ]} });复制代码

in/not in

db.activity.find({ event: {$in:[50,60,70]} });db.activity.find({ event: {$nin:[50,60,70]} });复制代码

count

db.activity.find().count();db.activity.find({ event: {$in:[50,60,70]} }).count();复制代码

distinct

db.activity.distinct("user_name");复制代码

sort

db.getCollection("activity").find({type:10}).sort({createTime:1});复制代码

时间段

查询某个时间段的数据

db.activity.find({createTime:{$gte:ISODate('2020-03-01T00:00:00.000Z'), $lte:ISODate( '2020-03-11T00:00:00.000Z' )}});复制代码

聚合

聚合查询

MongoDB中聚合(aggregate)主要用于处理数据(求平局值、求和等),并返回计算后的数据结果。类似sql中的group。

$sum求和

按user_id分组,求每个用户订单总额

db.order.aggregate([{$group : {_id : "$user_id", total_order_money: {$sum : "$order_money"}}}])复制代码

$avg求平均值

按user_id分组,求每个用户订单平均支付金额

db.order.aggregate([{$group : {_id : "$user_id", avg_order_money: {$avg : "$order_money"}}}])复制代码

$min求最小值

按user_id分组,求每个用户订单最小支付金额

db.order.aggregate([{$group : {_id : "$user_id", min_order_money: {$min : "$order_money"}}}])复制代码

$max 求最大值

按user_id分组,求每个用户订单最大支付额

db.order.aggregate([{$group : {_id : "$user_id", max_order_money: {$max : "$order_money"}}}])复制代码

$push

按user_id分组,查看每个用户所有的支付方式(不去重)

db.order.aggregate([{$group : {_id : "$user_id", payMethods: {$push: "$pay_method"}}}])复制代码

$addToSet

按user_id分组,查看每个用户所有的支付方式(去重)

db.order.aggregate([{$group : {_id : "$user_id", payMethods: {$addToSet : "$pay_method"}}}])复制代码

$first

按user_id分组,求每个用户第一笔订单金额

db.order.aggregate([{$group : {_id : "$user_id", first_order_money : {$first : "$order_money"}}}])复制代码

$last

按user_id分组,求每个用户最后笔订单金额

db.order.aggregate([{$group : {_id : "$user_id", last_order_money: {$last : "$order_money"}}}])复制代码

聚合管道

聚合管道是 MongoDB 2.2版本引入的新功能。它由阶段(Stage)组成,文档在一个阶段处理完毕后,聚合管道会把处理结果传到下一个阶段。

聚合管道功能:

  • 对文档进行过滤,查询出符合条件的文档
  • 对文档进行变换,改变文档的输出形式

下图是官网给出的聚合管道的流程图:

上图中,match 为筛选条件,将符合条件的数据筛选出来传递给下一阶段 $group 中进行分组求和计算,最后返回 Results。其中,match、$group 都是阶段操作符,而阶段 $group 中用到的 $sum 是表达式操作符。

常用阶段操作符

实例1(聚合查询)

按user_id分组,求每个用户订单状态为20的订单平均金额

mysql:select  user_id, avg(total_amount) from t_child_order where child_order_status=20group by merchant_code;mongo:db.t_child_order.aggregate( {$match:{child_order_status:20}}   ,       {$group:{_id:"$user_id",  avgDur:{$avg:"$total_amount" }}  });复制代码

其中,match表示查询条件;match表示查询条件;match表示查询条件;group表示通过user_id分组,并计算user_id相同值的visit_duration的平均数据。

实例2 (管道操作)

需求: 统计2020-03-01至2020-04-18期间,活动ID为1239575334792146946,且操作时间为查看活动详情页面(event:10)该活动每天的访问PV、每天的平均访问时长、每天的访问用户集合。

db.activity.aggregate([     //条件,筛选出来的数据,传入到下一阶段    {"$match" : { "activity_id" : '1239575334792146946', "create_time" : { "$lte" : ISODate( '2020-04-18T00:00:00.000Z' ), "$gte" : ISODate('2020-03-01T00:00:00.000Z') }, "event" : 10} },     //设置数据列的展示规则,然后传入到下一阶段    { "$project" :             { "create_time" : { "$dateToString" : { "format" : "%Y-%m-%d", "date" : "$create_time" } }, "visit_duration" : 1, "user_id" : 1                       }       },         //分组,计算数量、求和、求平均,然后传入到下一个阶段    { "$group" : { "_id" : "$create_time", "ALIAS_PAGE_PV" : { "$sum" : 1 }, "ALIAS_AVG_VISIT_DURATION" : { "$avg" : "$visit_duration" }, "ALIAS_USER_ARRAY" : { "$addToSet" : "$user_id" } }     },           //设置结果是否展示    { "$project" : { "_id" : 0, "create_time" : "$_id", "ALIAS_PAGE_PV" : 1, "ALIAS_AVG_VISIT_DURATION" : 1, "ALIAS_USER_ARRAY" : 1,  }     },         //排序    { "$sort" : { "create_time" : -1 } } ,    //限制结果条数     {"$limit":3}] );复制代码

查询结果如图:

Map Reduce

Map-Reduce是一种计算模型,可对复杂的计算分解执行,然后将结果合并。

使用 MapReduce 要实现Map 函数和 Reduce 函数。

Map 函数调用 emit(key, value), 遍历 collection 中所有的记录, 将 key 与 value 传递给 Reduce 函数进行处理。

Map 函数必须调用 emit(key, value) 返回键值对。

db.collection.mapReduce(   function() {emit(key,value);},  //map 函数   function(key,values) {return reduceFunction},   //reduce 函数   {      out: collection,      query: document,      sort: document,      limit: number   })复制代码
  • map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
  • reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组变成一个单一的值value。。
  • out 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
  • query 一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
  • sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
  • limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)

下图为MongoDB官网给出的Map-Reduce工作流程,从订单集合中,查找status为A的文档,按照cust_id分组,求每个cust_id的订单总额。

Map-Reduce使用实例

//统计每个用户的总访问时长db.activity.mapReduce(    function() {emit(this.user_id, this.visit_duration);},    function(key, values) {                         return Array.sum(values)                },    {        query: {            activity_id: "1236122613668032514",                        event:10        },                             out:"temp_result"    }).find();复制代码
//统计每个用户的平均访问时长db.activity.mapReduce(    function() {emit(this.user_id, this.visit_duration);},    function(key, values) {            var total= Array.sum(values);                var sizes= values.length;                return total/sizes                },    {        query: {            activity_id: "1236122613668032514",                        event:10        },                             out:"temp_result"    }).find();复制代码
//统计每个用户的访问该页面的次数db.activity.mapReduce(    function() {emit(this.user_id, 1);},    function(key, values) { return Array.sum(values)},    {        query: {            activity_id: "1236122613668032514",                        event:10        },                             out:"temp_result"    });db.temp_result.find();

mongodb 分组聚合_MongoDB干货总结相关推荐

  1. mongodb 分组聚合_mongodb 聚合命令

    MongoDB中聚合主要用于处理数据,如统计平均值,求和等等,并返回计算后的数据结果. 1. count count函数返回指定集合中的数量. > db. mediaCollection.cou ...

  2. mongodb 分组聚合_MongoDB按键值对进行聚合/分组

    我的数据看起来像这样: { "_id" : "9aa072e4-b706-47e6-9607-1a39e904a05a", "customerId&q ...

  3. mongodb 分组聚合_MongoDB学习笔记整理,赶紧收藏起来吧

    mongodb是最近几年最火的nosql数据库,在很多大型企业应用广泛,今天就一起学习它的用法.花了一周时间,整理下面的学习记录,希望对大家有所帮助. mongodb 1. mongodb的安装, w ...

  4. mongodb 分组聚合_MongoDB聚合嵌套分组

    我有资产收集,其中包含数据 { "_id" : ObjectId("5bfb962ee2a301554915"), "users" : [ ...

  5. MongoDB,分组,聚合

    使用聚合,db.集合名.aggregate- 而不是find 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数. MongoDB的聚合管道将MongoDB文档在一个管道处理 ...

  6. MongoDB多条件分组聚合查询

    MongoDB多条件分组聚合查询 1.样例数据 {"_id" : ObjectId("5fa13fb76c3107345a82c047"),"_cla ...

  7. MongoDB的使用学习之(七)MongoDB的聚合查询(spring-data-mongodb两种方式)附项目源码

    虽然只看了这一篇文章,但应该这个系列的文件应该都不错. http://www.cnblogs.com/ontheroad_lee/p/3756247.html 铛铛铛--项目源码下载地址:http:/ ...

  8. mongodb的聚合操作

    mongodb的聚合操作 1 mongodb的聚合是什么 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组.过滤等功 ...

  9. mongodb 聚合框架_如何使用MongoDB的聚合框架处理高级数据处理

    mongodb 聚合框架 MongoDB has come a long way. Even though there are many NoSQL databases out there, Mong ...

最新文章

  1. 完美解决latex警告信息:Citation `Gusfield:97‘ on page 1 undefined.
  2. 在matlab中将处理结果输出为shp文件
  3. 李宏毅机器学习(十)GPT-3
  4. 【C语言】Simple Sorting(结构)
  5. 新书榜TOP 20占了17位!榜单里有哪些值得入手的技术新书?
  6. Linux下JDK和Tomcat安装
  7. [4G+5G专题-143]: 一体化小基站-硬件架构设计概述
  8. 【寻找最佳小程序】影视评分小工具“豆瓣评分”——产品设计要点及专家评析...
  9. (六)jmeter接口自动化难点系列---jmeter使用base64解密
  10. 道德经 道可道,非常道。
  11. 奇偶数判断(YZOJ-1032)
  12. Android 设置背景透明
  13. chrome cookie存在什么地方_谷歌浏览器产生的cookie缓存怎么查看呢?Cookie的具体内容在哪里...
  14. windows蓝屏代码含意全集
  15. 点击a标签,返回上一页
  16. java环境安装完毕,运行web项目报javax annotation managedbean unsup错误
  17. 〖Python 数据库开发实战 - MySQL篇⑯〗- SQL 语句的条件查询
  18. 【PDF】Adobe acrobat如何加注释
  19. 如何检测支付宝名字性别
  20. JDK源码系列:子线程如何继承父线程上通过ThreadLocal绑定的数据

热门文章

  1. java sort方法_Java排序方法sort用法详解
  2. mysql mysqld.log_MySQL mysqlbinlog 读取mysql-bin文件出错
  3. QT不同线程间signal-slot机制的值传递
  4. 互联网产品开发中的“快”字诀
  5. 通过HTTP的HEADER完成各种骚操作
  6. zabbix 自动发现
  7. Xshell利用密钥远程登录Linux
  8. 创建Windows Mobile上兼容性好的UI 程序
  9. 遇到了arcgis server9.1 在web开发的问题
  10. 分发服务器linux,Linux-LVS分发服务器