MongoDB 小记
之前本人说过一款非关系型数据库的代表 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 小记的更多相关文章
- MongoDB小记
mongodb的一个简单使用. package com.chuntent.mongo; import java.util.Map; import java.util.Map.Entry; import ...
- mongodb入门学习小记
Mongodb 简单入门(个人学习小记) 1.安装并注册成服务:(示例) E:\DevTools\mongodb3.2.6\bin>mongod.exe --bind_ip 127.0.0.1 ...
- Java程序中与MongoDB建立连接~小记
1.Mongo和MongoClient的关系 MongoClient继承自Mongo,使用Mongo也可建立连接,但是需要使用与Mongo适应的MongoOptions,MongoURI等类型. 2. ...
- mongoDB使用小记
1.简介: MongoDB是由c++语言编写的,基于分布式文件存储的开源数据库系统.MongoDB将数据存储为一个文档,数据结构有键-值对,类似于JSON对象. MongoDB其中的一些概念如下: M ...
- 小记------mongodb数据库如何进行模糊查询
// 模糊匹配createTime 是以 2019-07-23 开头 db.getCollection('driver_online_record').find({"createTime ...
- linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记
上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...
- MongoDB学习记录
一.操作符 "$lt" :"<""$lte" :"<=""$gt" :"> ...
- Java JPA小记
什么是JPA JPA之于ORM(持久层框架,如MyBatis.Hibernate等)正如JDBC之于数据库驱动. JDBC是Java语言定义的一套标准,规范了客户端程序访问关系数据库(如MySQL.O ...
- [转帖]「日常小记」linux中强大且常用命令:find、grep
「日常小记」linux中强大且常用命令:find.grep https://zhuanlan.zhihu.com/p/74379265 在linux下面工作,有些命令能够大大提高效率.本文就向大家介绍 ...
随机推荐
- 妙用this关键字
妙用this关键字 ## this关键字一般this关键字都是指的是对象的本身,在类的所有方法.构造器都可以拿到this引用,这是jvm"偷偷"帮我们传递进来的引用,指向调用方法对 ...
- 洛谷 P1129 解题报告
P1129 [ZJOI2007]矩阵游戏 题目描述 小\(Q\)是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个\(N*N\)黑白方阵进行(如同国际象棋一般 ...
- Redis之实战篇(与Mybatis整合)
摘要: 现在市面流行的java框架,一个是ssh(spring.struts2.hibernate),另一个是ssm(spring.springmvc.mybatis),由于之前已经有整合过ssm框架 ...
- linux 下 Emacs dired 模式 隐藏 dot file ".filename" 文件
有时候 emacs 下调用 C-x dired 是挺方便的一个事,但是一堆的点文件(linux下以"."为前缀的文件,即隐藏文件)让人目不暇接,打算隐藏之. 参考如下: 最主要的是 ...
- Python基础之数据类型、变量、常量
数据类型 整数:任意大小的整数,十六进制用0x前缀 浮点数:浮点数也就是小数,科学计数法1.23x109就是1.23e9,0.000012可以写成1.2e-5 字符串:以单引号'或双引号"括 ...
- Java VisualVM无法检测到本地java程序 的 解决办法
win10系统下启动jvisualvm应用,报"VisualVM无法检测到本地java程序"的错误!在网上查了一些方法, 大概原因有2种: 1.操作系统的临时文件目录所在的磁盘格式 ...
- Centos7下安装PHP5.5,5.6,7.0----(转载记录一下)
由于centOS7 默认的php版本是5.4的,偏低,所以收录了一下怎样安装5.5/5.6/7.0版本 默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的 ...
- 树莓派.Raspberry Pi 3碰到"Unable to determine hardware version. I see: Hardware : BCM2835"错误的解决过程
按pi4jp官方的安装指导(http://pi4j.com/install.html)进行安装 curl -s get.pi4j.com | sudo bash 安装完成后执行JAVA程序, 发现如下 ...
- CString 转化成 const char* 类型
写程序的时候经常会遇到无法将“CString”转换为“const char *”的错误,这里我找到了一个解决办法,与大家分享下: CString cs = _T("); ) * ; char ...
- bzoj3199 [Sdoi2013]escape
这题真tm是醉了. 就是对于每个亲戚,利用其它的亲戚对他半平面交求出其控制的范围,然后随便跑个最短路就行了 n=0卡了我一下午////// #include <cstdio> #inclu ...