ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

初识MongoDB(十二) MongoDB管道操作符一

2021-12-21 10:33:29  阅读:208  来源: 互联网

标签:agg MongoDB db project 初识 操作符 freight aggregate orderDate


熟悉Linux系统的小伙伴应该知道Linux中有管道的说法,可以用来方便地处理数据。

MongoDB 2.2版本也引入了新的数据聚合框架,一个文档可以经过多个节点组成的管道,每个节点都有自己特殊的功能,比如文档分组、文档过滤等。每一个节点都会接收一连串的文档,对这些文档做一些类型转换,然后将转换后的文档传递给下一个节点,最后一个节点则会将结果返回给客户端。本文先来看几个基本的管道操作符。

$match

$match 可以用来对文档进行筛选。筛选完成之后,我们就可以在筛选获得到的文档子集上做数据聚合操作了。我们之前介绍的查询的操作符在 $match 中都可以使用,比如获取集合中所有 author为"杜甫"的文档,如下:

db.agg_1.aggregate({$match:{author:"杜甫"}})

我们在实际使用时最好将 $match 放在管道的前面,这样可以减少后边管道的工作量。同时,我们在投射和分组之前执行 $match 还可以用索引。

$project

基本用法

$project可以用来提取想要的字段,如下:

db.agg_1.aggregate({$project:{title:1,_id:0}})

1表示要该字段,0表示不要该字段。也可以对返回的字段进行重命名,比如将 title 改为 articleTitle ,如下:

db.agg_1.aggregate({$project:{"articleTitle":"$title"}})

不过这里有一个问题需要注意:如果原字段上有索引,重命名之后的字段上就没有索引了,因此最好在重命名之前使用索引。

数学表达式

数学表达式可以用来对一组数值进行加减乘除取模,比如我的数据结构如下:

{
    "_id":ObjectId("61a71128fcabfe7d198aac94"),
    "orderAddressL":"shenzhen",
    "prodMoney":45,
    "freight":13,
    "discounts":3,
    "orderDate":ISODate("2021-12-01T06:07:36.517Z"),
    "prods":[
        "可乐",
        "奶茶"
    ]
}

订单的总费用为商品费用加上运费,查询如下:

db.agg_2.aggregate({$project:{totalMoney:{$add:["$prodMoney","$freight"]}}})

实际付款的费用是总费用减去折扣,如下:

db.agg_2.aggregate({$project:{totalPay:{$subtract:[{$add:["$prodMoney","$freight"]},"$discounts"]}}})

再来三个无厘头运算,比如计算 prodMoney 和 freight 和 discounts 的乘积,如下:

db.agg_2.aggregate({$project:{test1:{$multiply:["$prodMoney","$freight","$discounts"]}}})

再比如求 prodMoney 和 freight 的商,如下:

db.agg_2.aggregate({$project:{test2:{$divide:["$prodMoney","$freight"]}}})

再比如用 freight 对 prodMoney 取模,如下:

db.agg_2.aggregate({$project:{test3:{$mod:["$freight","$prodMoney"]}}})

加法和乘法都可以接收多个参数,其余的都接收两个参数。

日期表达式

日期表达式可以从一个日期类型中提取出年、月、日、星期、时、分、秒等信息,如下:

db.agg_2.aggregate({$project:{"年份":{$year:"$orderDate"},
"月份":{$month:"$orderDate"},"一年中第几周":{$week:"$orderDate"},
"日期":{$dayOfMonth:"$orderDate"},"星期":{$dayOfWeek:"$orderDate"},
"一年中第几天":{$dayOfYear:"$orderDate"},"时":{$hour:"$orderDate"},
"分":{$minute:"$orderDate"},"秒":{$second:"$orderDate"},
"毫秒":{$millisecond:"$orderDate"},
"自定义格式化时间":{$dateToString:{format:"%Y年%m月%d日 %H:%M:%S",date:"$orderDate"}}}})

执行结果如下:

{
    "_id":ObjectId("61a71128fcabfe7d198aac94"),
    "年份":2021,
    "月份":12,
    "一年中第几周":48,
    "日期":1,
    "星期":4,
    "一年中第几天":335,
    "时":6,
    "分":7,
    "秒":36,
    "毫秒":517,
    "自定义格式化时间":"2021年12月01日 06:07:36"
}

$dayOfWeek 返回的是星期,1表示星期天,7表示星期六。$week 表示本周是本年的第几周,从0开始计。$dateToString 是MongoDB 3.0+中的功能,格式化的字符还有以下几种:

字符含义取值范围
%YYear (4 digits, zero padded)0000-9999
%mMonth (2 digits, zero padded)01-12
%dDay of Month (2 digits, zero padded)01-31
%HHour (2 digits, zero padded, 24-hour clock)00-23
%MMinute (2 digits, zero padded)00-59
%SSecond (2 digits, zero padded)00-59
%LMillisecond (3 digits, zero padded)000-999
%jDay of Year (3 digits, zero padded)001-366
%wDay of Week (1-Sunday,7-Saturday)1-7
%UWeek of Year (2 digits, zero padded)00-53

字符串表达式

字符串表达式中有字符串的截取、拼接、转大写、转小写等操作,比如我截取 orderAddressL 前两个字符返回,如下:

db.agg_2.aggregate({$project:{addr:{$substr:["$orderAddressL",0,2]}}})

再比如我将 orderAddressL 和 orderDate 拼接后返回:

db.agg_2.aggregate({$project:{test1:{$concat:["$orderAddressL",{$dateToString:{format:"%Y年%m月%d日 %H:%M:%S",date:"$orderDate"}}]}}})

再比如我将 orderAddressL 全部转为小写返回:

db.agg_2.aggregate({$project:{test1:{$toLower:"$orderAddressL"}}})

再比如我将 orderAddressL 全部转为大写返回:

db.agg_2.aggregate({$project:{test1:{$toUpper:"$orderAddressL"}}})

逻辑表达式

想要比较两个数字的大小,可以使用 $cmp 操作符,如下:

db.agg_2.aggregate({$project:{test1:{$cmp:["$freight","$discounts"]}}})

如果第一个参数大于第二个参数返回正数,第一个参数小于第二个参数则返回负数。也可以利用 $strcasecmp 来比较字符串(中文无效):

db.agg_2.aggregate({$project:{test1:{$strcasecmp:["$orderAddressL",{$dateToString:{format:"%Y年%m月%d日",date:"$orderDate"}}]}}})

至于我们之前介绍的 $eq / $ne / $gt / $gte / $lt / $lte 等操作符在这里一样是适用的。另外还有 $and、$or、$not 等表达式可用,以 $and 为例,如下:

db.agg_2.aggregate({$project:{test1:{$and:[{$eq:["$freight","$prodMoney"]},{$eq:["$freight","$discounts"]}]}}})

$and 中的每个参数都为 true 时返回 true。$or 则表示参数中有一个为 true 就返回 true。$not 则会对它的参数的值取反,如下:

db.agg_2.aggregate({$project:{test1:{$not:{$eq:["$freight","$discounts"]}}}})

另外还有两个流程控制语句,如下:

db.agg_2.aggregate({$project:{test1:{$cond:[false,"trueExp","falseExp"]}}})

$cond 第一个参数如果为 true,则返回 trueExp,否则返回 falseExp。

db.agg_2.aggregate({$project:{test1:{$ifNull:[null,"replacementExp"]}}})

$ifNull 第一个参数如果为 null,就返回 replacementExp,否则就返回第一个参数。

标签:agg,MongoDB,db,project,初识,操作符,freight,aggregate,orderDate
来源: https://blog.csdn.net/tingyu1995/article/details/122056218

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有