MongoDB 小记

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

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

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

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

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

sudo mongod --dbpath /usr/local/mongodb/data/db/

安装并配置好 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 在数据的操作方面语法还是很贴切我们的日常操作语法的,用起来也很方便。

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

 

posted @ 2019-04-22 09:14  丰寸  阅读(488)  评论(1编辑  收藏  举报