查询操作
简单查询
以MySQL查询和MongoDB查询,做对比供大家学习。
select * from spu where spu_name="test0123"
db.spu.find({ spu_name:"test0123" })
and
select * from spu where spu_name="test0123" and type=3
db.spu.find({spu_name:"test0123", type:"3" });
like
select * from user where username like "%test0123%"
db.user.find({username:/test0123/});
大于等于、小于等于
//大于、大于等于、小于、小于等于 $lt, $lte, $gt, $gte
select * from user where age>=10 and age<=20
db.user.find({ age:{$gte:10, $lte:20} });
等于null
select * from user where address is null
db.user.find({ address: null });
不为null
select * from user where address is not null
db.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为筛选条件,将符合条件的数据筛选出来传递给下一阶段match 为筛选条件,将符合条件的数据筛选出来传递给下一阶段 match为筛选条件,将符合条件的数据筛选出来传递给下一阶段group 中进行分组求和计算,最后返回 Results。其中,match、match、match、group 都是阶段操作符,而阶段 group中用到的group 中用到的 group中用到的sum 是表达式操作符。
常用阶段操作符
阶段操作符 | 描述 |
---|---|
$project | 修改文档的结构,可以用来重命名、增加或删除文档中的字段。 |
$match | 过滤条件。$match 尽量出现在管道的最前面,过滤出需要的数据,在后续的阶段中可以提高效率。 |
$group | 分组 |
$sort | 排序 |
$limit | 限制结果条数,可用于实现分页查询 |
$skip | 跳过指定数量的文档,并返回余下的文档。 |
$unwind | 将文档中数组类型的字段拆分成多条,每条文档包含数组中的一个值。 |
实例1(聚合查询)
按user_id分组,求每个用户订单状态为20的订单平均金额
mysql:
select user_id, avg(total_amount) from t_child_order
where child_order_status=20
group 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}
]
);
查询结果如图: