MongoDB进阶——高级查询和聚合统计(aggregate)

MongoDB初识——安装连接(centos)
https://blog.csdn.net/maxmao1024/article/details/84426836

MongoDB入门——增删改查
https://blog.csdn.net/maxmao1024/article/details/84528649

1. 数据准备

> use test
> db.event.drop()
> db.event.insertMany([
{'event_id': 1, 'user_id': 1002, 'date': '2018-11-02'}
,{'event_id': 2, 'user_id': 1002, 'date': '2018-11-02'}
,{'event_id': 3, 'user_id': 1002, 'date': '2018-11-02'}
,{'event_id': 1, 'user_id': 1003, 'date': '2018-11-03'}
,{'event_id': 1, 'user_id': 1004, 'date': '2018-11-03'}
])

> db.event.find()
{ "_id" : ObjectId("5bfb68a511241f1551cacd9d"), "event_id" : 1, "user_id" : 1002, "date" : "2018-11-02" }
{ "_id" : ObjectId("5bfb68a511241f1551cacd9e"), "event_id" : 2, "user_id" : 1002, "date" : "2018-11-02" }
{ "_id" : ObjectId("5bfb68a511241f1551cacd9f"), "event_id" : 3, "user_id" : 1002, "date" : "2018-11-02" }
{ "_id" : ObjectId("5bfb68a511241f1551cacda0"), "event_id" : 1, "user_id" : 1003, "date" : "2018-11-03" }
{ "_id" : ObjectId("5bfb68a511241f1551cacda1"), "event_id" : 1, "user_id" : 1004, "date" : "2018-11-03" }

# 数据准备完毕,下面的查询等操作为了节约篇幅,一般不展示查询结果,有兴趣的同学可以自己尝试

2. find

> db.event.find({event_id:1})
# 基本查找语句, 返回3条文档

db.event.find({event_id:'1'})
# 与mysql 不同的是,mongo在查找时不会自动做类型转换,所以这个查询的返回结果为空

> db.event.find({event_id:1}).skip(1).limit(1)
# skip 和 limit 的使用, 返回1条文档

> db.event.find({event_id:1}).count()
> db.event.count()
> db.event.count({'event_id': 1})
# count 的使用

> db.event.distinct('event_id')
> db.event.distinct('event_id', {'user_id': 1003})
# distinct 的使用, 第一个是去重字段,第二个大括号里的是筛选条件
# 很遗憾的是distinct 后面不能接count了,后面会提到如何处理

> db.event.find({event_id:{$in:[1, 2]}})

> db.event.find({event_id:{$gt:1, $lt:3}})
# 范围查找,$gt, $lt, $gte, $lte

> db.event.find({'date': /2018/})
# 模糊查找,注意只对字符串类型的字段适用,例如user_id 就无法用模糊查找

> db.event.find({event_id:1}).explain()
# explain 的使用,和mysql类似,主要看使用索引的情况

> db.event.find({user_id:{$in:[null]}})  -- 为 null或不存在
> db.event.find({user_id:null}) -- 为 null或不存在
> db.event.find({user_id:{$in:[null],$exists:true}})  -- 存在且为null
> db.event.find({user_id:{$ne:null}}) -- 不为null
# 关于 null、not null 和 exists 的一些处理方法

3. index

> db.event.getIndexes()
# 查看集合的所有索引,默认会有 _id 字段的索引

> db.event.ensureIndex({"event_id": 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
# 添加索引

> db.event.ensureIndex({"event_id": 1}, {background: 1}) 
# 在后台添加索引,在集合比较大的时候必须使用后台添加,否则会阻塞其他操作,
# 这里会报错因为重复添加索引

> db.event.ensureIndex({"user_id": 1}, {'unique': true})
# 添加唯一索引,这里会报错因为 user_id 不唯一

> db.event.find({event_id:1}).explain()
# 这时候就能看到 'winningPlan' 里有了查找使用的索引信息

> db.event.dropIndex({'event_id': 1})
# 删除索引

4. aggregate 操作

官方文档
https://docs.mongodb.com/v3.6/reference/operator/aggregation-pipeline/

这里只介绍几种常用操作

$match: 查找条件匹配
$project: 字段筛选, 也可以用来重命名字段
$group: 聚合操作,类似mysql的 group by
$sort: 排序

下面我们结合具体的统计需求进行运用

  • 查找 user_id 为1002的文档,只保留event_id 字段
> db.event.aggregate([
{$match: {"user_id": 1002}},
{$project: {"_id": 0, "event_id": 1}}
])

{ "event_id" : 1 }
{ "event_id" : 2 }
{ "event_id" : 3 }
  • 分别统计每个event_id的记录总数,按数量由多到少排序
> db.event.aggregate([
{$group: {"_id": "$event_id", count: {$sum: 1}}},
{$project: {"_id": 0, "event_id": "$_id", "count": 1}},
{$sort: {"count": -1}}
])

{ "count" : 3, "event_id" : 1 }
{ "count" : 1, "event_id" : 3 }
{ "count" : 1, "event_id" : 2 }

你可能感兴趣的:(大数据,数据库,MongoDB)