之前本人说过一款非关系型数据库的代表 Redis 的 《 Redis 小记 》文章,觉得意犹未尽,今天就来介绍一款数据库 MongoDB ,先来看一下

MongoDB是一款基于分布式文件存储的数据库,是一种文档型数据库,是介于关系型和非关系型数据库之间的产品,是最接近关系型数据库的数据库。MongoDB中的每一条记录就是一个文档,是一个数据结构,由字段和值对组成,字段的值可能其他文档,数组,以及文档数组。一般用作离线数据分析使用,放在内网居多,提供高性能的数据持久化。

以上为网上对于 MongoDB 的解释,总结起来就是一句话:好!

老规矩,话不多说,直接开撸。

关于 MongoDB 的安装就不介绍了,大家根据电脑版本型号自行搜索安装。

安装并配置好 MongoDB 后我们在终端输入 db 及 show dbs 出现以下内容说明安装成功。MongoDB 默认数据库为 test 数据库,我们也可以自己创建数据库,如下。

MongoDB 在创建数据库上还是很方便的,如上图,use test1 表示如果有 test1 这个数据库就切换到该数据库,如果没有则创建并切换到该数据库,通过 db 命令查看当前使用的数据库并且可以删除该数据库。

如上图,db.createCollection( name , options ) 可以创建集合,其中 name 为必填项,为集合的名称,options 为可选项,选项中 capped 默认值为 false 表示不设置上限,值为 true 表示设置上限;当 capped 值为 true 时需设置 size 值,size 值为集合的上限,当超过上限时再插入数据会将之前的数据覆盖,单位为字节。

如上图,MongoDB 通过 db.集合名称.insert( ) 向集合中添加数据,可以通过 db.集合名称.update( ) 对集合进行数据更新,db.集合名称.find() 对数据进行查找,操作中其实还有很多选填项,这个稍后会说。

db.集合名称.remove( ) 可以对集合进行删除,第一个 { } 表示要删除数据的匹配项,第二个 { } 表示删除多个还是一个,true 表示只删除匹配到的第一个,false 表示删除匹配到的所有数据,db.集合名称.remove( { } ) 表示删除所有数据。

从上面对 MongoDB 增删改查的基本操作我们发现其语法很接近 JavaScript 这类语言,对于我们这种初学者还是很友好的。但是语法上要比之前说过的 Redis 复杂一些,所以接下来的操作就不在终端进行操作了,移驾 Robo 3T (萝卜) 软件。

图标就是上面这个长得跟萝卜似的大眼仔,直接下载安装即可。打开软件我们先进行如下配置。

因为我们是在本地测试,所以 ip 为 127.0.0.1,端口号用 MongoDB 默认的 27017 端口。点击 Save 保存之后点击 Connect 进行连接即可。

进来之后我们发现在错侧栏我们之前在终端创建的 test2 数据库还在,我们可以选中右键对其进行操作。我们也可以选中下方的 Collections 对其进行集合的操作,这些大家安装之后操作一下就可以了,很方便。右侧最上面黑条内可以输入我们想要的操作,对应的在下方会看到操作的输出结果,话不多说,操作起来。

我们在之前终端创建的集合内插入 5 条数据,在软件右上角除可以对数据的显示状态进行切换。

我们将其展示为直观的 json 数据格式。我们可以看出,在使用 MySQL 等关系型数据库时,主键都是设置自增的,但是在分布式环境下,这种方法就不可行了,会产生冲突,为此,MongoDB 采用了一个称之为 ObjectId 的类型来做主键,是一个随机生成的 BSON 类型的字符串,具体含义大家自行百度,不是重点。

数据库中大部分操作都是围绕查询来进行操作的,这里我们着重看一下 MongoDB 在数据查询方面的写法。

基本查询

方法find():查询

db.集合名称.find({条件文档})

方法findOne():查询,只返回第一个

db.集合名称.findOne({条件文档})

方法pretty():将结果格式化

db.集合名称.find({条件文档}).pretty()

比较运算符

  • 等于,默认是等于判断,没有运算符

  • 小于$lt

  • 小于或等于$lte

  • 大于$gt

  • 大于或等于$gte

  • 不等于$ne

  • 例1:查询名称等于'nan1'的人

db.user.find({name:'nan1'})

运行结果如下:

例2:查询年龄大于或等于18的人

db.user.find({age:{$gte:18}})

逻辑运算符

  • 查询时可以有多个条件,多个条件之间需要通过逻辑运算符连接

  • 逻辑与:默认是逻辑与的关系

  • 例3:查询年龄大于或等于20,并且性别为true的人

db.user.find({age:{$gte:18},gender:true})

逻辑或:使用$or

例4:查询年龄大于20,或性别为 false 的人

db.user.find({$or:[{age:{$gt:18}},{gender:false}]})

运行结果如下:

and和or一起使用

例5:查询年龄大于18或性别为 true 的人,并且人的姓名为nan2

db.user.find({$or:[{age:{$gte:18}},{gender:true}],name:'nan2'})

运行结果如下:

范围运算符

使用"$in","$in" 判断是否在某个范围内

例6:查询年龄为18、28的人

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

支持正则表达式

使用//或$regex编写正则表达式

例7:查询姓nan的人

db.user.find({name:/^nan/})
db.user.find({name:{$regex:'^nan'}}})

自定义查询

使用$where后面写一个函数,返回满足条件的数据

例7:查询年龄大于20的人

db.user.find({$where:function(){return this.age>20}})

Limit

方法limit():用于读取指定数量的文档

语法:

db.集合名称.find().limit(NUMBER)

参数NUMBER表示要获取文档的条数

如果没有指定参数则显示集合中的所有文档

例1:查询2条信息

db.user.find().limit(2)

skip

方法skip():用于跳过指定数量的文档

语法:

db.集合名称.find().skip(NUMBER)

参数NUMBER表示跳过的记录条数,默认值为0

例2:查询从第3条开始的user信息

db.user.find().skip(2)

一起使用

方法limit()和skip()可以一起使用,不分先后顺序

创建数据集

for(i=0;i<15;i++){db.user.insert({_id:i})}

查询第2至3条数据

db.user.find().limit(2).skip(1)

db.user.find().skip(1).limit(2) 

运行结果如下:

投影

在查询到的返回结果中,只选择必要的字段,而不是选择一个文档的整个字段

如:一个文档有5个字段,需要显示只有3个,投影其中3个字段即可

语法:

参数为字段与值,值为1表示显示,值为0不显示

db.集合名称.find({},{字段名称:1,...})

对于需要显示的字段,设置为1即可,不设置即为不显示

特殊:对于_id列默认是显示的,如果不显示需要明确设置为0

例1

db.user.find({},{name:1,gender:1})

例2

db.user.find({},{_id:0,name:1,gender:1})

运行结果如下:

排序

方法sort(),用于对结果集进行排序

语法

db.集合名称.find().sort({字段:1,...})

参数1为升序排列

参数-1为降序排列

例1:根据性别降序,再根据年龄升序

db.user.find().sort({gender:-1,age:1})

统计个数

方法count()用于统计结果集中文档条数

语法

db.集合名称.find({条件}).count()

也可以与为

db.集合名称.count({条件}) 

例1:统计男人数

db.user.find({gender:true}).count()

例2:统计年龄大于20的男人数

db.user.count({age:{$gt:20},gender:true})

运行结果如下

消除重复

方法distinct()对数据进行去重

语法

db.集合名称.distinct('去重字段',{条件})

例:查找年龄大于18的性别(去重)

db.user.distinct('gender',{age:{$gt:18}})

运行结果如下:

以上就是 MongoDB 在数据查询方面的基本操作,基本够我们的操作使用了。

接下来我们说一下 MongoDB 语法中的高级应用 aggregate(聚合)。聚合主要用于计算数据,类似于 sql 中的 sum( ),avg( )。

db.集合名称.aggregate([{管道:{表达式}}])

管道

管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的输入

ps ajx | grep mongo

在mongodb中,管道具有同样的作用,文档处理完毕后,通过管道进行下一次处理

常用管道

  • $group:将集合中的文档分组,可用于统计结果

  • $match:过滤数据,只输出符合条件的文档

  • $project:修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

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

  • $limit:限制聚合管道返回的文档数

  • $skip:跳过指定数量的文档,并返回余下的文档

  • $unwind:将数组类型的字段进行拆分

表达式

处理输入文档并输出

语法

表达式:'$列名'
  • 常用表达式

    • $sum:计算总和,$sum:1同count表示计数

    • $avg:计算平均值

    • $min:获取最小值

    • $max:获取最大值

    • $push:在结果文档中插入值到一个数组中

    • $first:根据资源文档的排序获取第一个文档数据

    • $last:根据资源文档的排序获取最后一个文档数据

我们先看看之前我们添加进去的数据,我们在 user 集合中添加了五条数据,有 name ,age,gender 字段,其中 gender 字段 true 表示男,false 表示女。

$group

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

_id表示分组的依据,使用某个字段的格式为'$字段'

例:统计男人、女人的总人数

db.user.aggregate([
{$group:
{
_id:'$gender',
counter:{$sum:1}
}
}
])

运行结果如下:

Group by null

将集合中所有文档分为一组

例2:求总人数、平均年龄

db.user.aggregate([
{$group:
{
_id:null,
counter:{$sum:1},
avgAge:{$avg:'$age'}
}
}
])

运行结果如下:

透视数据

例3:统计 user 性别及姓名

db.user.aggregate([
{$group:
{
_id:'$gender',
name:{$push:'$name'}
}
}
])

运行结果如下:

使用$$ROOT可以将文档内容加入到结果集的数组中,代码如下

db.user.aggregate([
{$group:
{
_id:'$gender',
name:{$push:'$$ROOT'}
}
}
])

运行结果如下:

$match

用于过滤数据,只输出符合条件的文档

使用MongoDB的标准查询操作

例:查询年龄大于20的人

db.user.aggregate([
{$match:{age:{$gt:20}}}
])

运行结果如下:

例:查询年龄大于20的男人、女人人数

db.user.aggregate([
{$match:{age:{$gt:20}}},
{$group:{_id:'$gender',counter:{$sum:1}}}
])

运行结果如下:

$project

修改输入文档的结构,如重命名、增加、删除字段、创建计算结果

例:查询 user 的姓名、年龄

db.user.aggregate([
{$project:{_id:0,name:1,age:1}}
])

运行结果如下:

例:查询男人、女人人数,输出人数

db.user.aggregate([
{$group:{_id:'$gender',counter:{$sum:1}}},
{$project:{_id:0,counter:1}}
])

运行结果如下:

$sort

将输入文档排序后输出

例:查询 user 信息,按年龄升序

db.user.aggregate([{$sort:{age:1}}])

运行结果如下:

例:查询男人、女人人数,按人数降序

db.user.aggregate([
{$group:{_id:'$gender',counter:{$sum:1}}},
{$sort:{counter:-1}}
])

运行结果如下:

$limit

限制聚合管道返回的文档数

例:查询2条 user 信息

db.user.aggregate([{$limit:2}])

运行结果如下:

$skip

跳过指定数量的文档,并返回余下的文档

例:查询从第3条开始的 user 信息

db.user.aggregate([{$skip:2}])

运行结果如下:

例3:统计男人、女人人数,按人数升序,取第二条数据

注意顺序:先写skip,再写limit

db.user.aggregate([
{$group:{_id:'$gender',counter:{$sum:1}}},
{$sort:{counter:1}},
{$skip:1},
{$limit:1}
])

运行结果如下:

以上就是关于 MongoDB 聚合的一些操作,MongoDB 还有配置用户管理和设置数据库主从关系等操作,由于此篇幅过长,实在是写的太累了,有机会再说一下吧。

总的来说 MongoDB 在数据的操作方面语法还是很贴切我们的日常操作语法的,用起来也很方便。

好记性不如烂笔头,特此记录,与君共勉!

MongoDB 小记的更多相关文章

  1. MongoDB小记

    mongodb的一个简单使用. package com.chuntent.mongo; import java.util.Map; import java.util.Map.Entry; import ...

  2. mongodb入门学习小记

    Mongodb 简单入门(个人学习小记) 1.安装并注册成服务:(示例) E:\DevTools\mongodb3.2.6\bin>mongod.exe --bind_ip 127.0.0.1 ...

  3. Java程序中与MongoDB建立连接~小记

    1.Mongo和MongoClient的关系 MongoClient继承自Mongo,使用Mongo也可建立连接,但是需要使用与Mongo适应的MongoOptions,MongoURI等类型. 2. ...

  4. mongoDB使用小记

    1.简介: MongoDB是由c++语言编写的,基于分布式文件存储的开源数据库系统.MongoDB将数据存储为一个文档,数据结构有键-值对,类似于JSON对象. MongoDB其中的一些概念如下: M ...

  5. 小记------mongodb数据库如何进行模糊查询

    // 模糊匹配createTime   是以 2019-07-23 开头 db.getCollection('driver_online_record').find({"createTime ...

  6. linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记

    上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...

  7. MongoDB学习记录

    一.操作符 "$lt" :"<""$lte" :"<=""$gt" :"> ...

  8. Java JPA小记

    什么是JPA JPA之于ORM(持久层框架,如MyBatis.Hibernate等)正如JDBC之于数据库驱动. JDBC是Java语言定义的一套标准,规范了客户端程序访问关系数据库(如MySQL.O ...

  9. [转帖]「日常小记」linux中强大且常用命令:find、grep

    「日常小记」linux中强大且常用命令:find.grep https://zhuanlan.zhihu.com/p/74379265 在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍 ...

随机推荐

  1. Spring4托管Hibernate5并利用HibernateTemplate进行数据库操作

    时隔半年,再次发布配置类的相关Blog,因为左手受伤原因先做一个简述. 首先利用idea创建一个Spring+SpringMVC+Hibernate项目,注意的是因为我们要完全放弃Hibernate以 ...

  2. (ospf、rip、isis、EIGRP)常见的动态路由协议简介

    路由器要转发数据必须先配置路由数据,通常根据网络规模的大小可设置静态路由或设置动态路由.静态路由配置方便,对系统要求低,适用于拓扑结构简单并且稳定的小型网络.缺点是不能自动适应网络拓扑的变化,需要人工 ...

  3. larave5.4自定义公共函数的创建

    原文地址:http://blog.csdn.net/qq_38125058/article/details/76862151 公共函数,简单来说就是在任何地方都可以直接使用这个函数.简单介绍两种实现方 ...

  4. Python_自定义有向图

    directedGraph.py class DirectedGraph(object): def __init__(self,d): if isinstance(d,dict): self.__gr ...

  5. Ubuntu 16.04 安装 Docker

    在Ubuntu上安装Docker, 非常简单, 我测试过 16.04, 17.04, 以及最新版 18.04,都是可以成功安装,并使用的. 第一步:  启动root账号 第二步:  配置网络,能上网 ...

  6. PAT1021:Deepest Root

    1021. Deepest Root (25) 时间限制 1500 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph ...

  7. javascript 正则(将数字转化为三位分隔的样式)

    '12345678912345678'.replace(/\B(?=(?:\d{3})+\b)/g, ',') 解释: \b : 匹配单词边界,就是位于字符\w([a-zA-Z0-9_])和\W[^a ...

  8. Netty中如何写大型数据

    因为网络饱和的可能性,如何在异步框架中高效地写大块的数据是一个特殊的问题.由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture.当这种情况发生时,如 ...

  9. Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()

    我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子系统,在时间子系统中提供了一些用于延时或调度的API,例如msleep,hrtimer_nanosleep等等,这些A ...

  10. Load balancer does not have available server for client

    最近在研究spring-cloud,研究zuul组件时发生下列错误: Caused by: com.netflix.client.ClientException: Load balancer does ...