mongonr日期对应java_MongoDB管道操作符(一)

熟悉Linux操作系统的小伙伴们应该知道Linux中有管道的说法,可以用来方便的处理数据。MongoDB2.2版本也引入了新的数据聚合框架,一个文档可以经过多个节点组成的管道,每个节点都有自己特殊的功能,比如文档分组、文档过滤等,每一个节点都会接受一连串的文档,对这些文档做一些类型转换,然后将转换后的文档传递给下一个节点,最后一个节点则会将结果返回给客户端。本文我们就先来看几个基本的管道操作符。

本文是MongoDB系列的第十二篇文章,了解前面的文章有助于更好的理解本文:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

$match

match中都可以使用,比如获取集合中所有author为”杜甫”的文档,如下:

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

我们在实际使用时最好将match还可以用索引。

$project

基本用法

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

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

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

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

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

数学表达式

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

{

"_id" : ObjectId("59f841f5b998d8acc7d08863"),

"orderAddressL" : "ShenZhen",

"prodMoney" : 45.0,

"freight" : 13.0,

"discounts" : 3.0,

"orderDate" : ISODate("2017-10-31T09:27:17.342Z"),

"prods" : [

"可乐",

"奶茶"

]

}

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

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

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

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

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

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

再比如求freight的商,如下:

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

再比如用prodMoney取模,如下:

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

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

日期表达式

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

db.sang_collect.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("59f841f5b998d8acc7d08861"),

"年份" : 2017,

"月份" : 10,

"一年中第几周" : 44,

"日期" : 31,

"星期" : 3,

"一年中第几天" : 304,

"时" : 9,

"分" : 27,

"秒" : 17,

"毫秒" : 342,

"自定义格式化时间" : "2017年10月31 09:27:17"

}

week表示本周是本年的第几周,从0开始计。$dateToString是MongoDB3.0+中的功能。格式化的字符还有以下几种:

字符串表达式

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

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

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

db.sang_collect.aggregate({$project:{addr:{$concat:["$orderAddressL",{$dateToString:{format:"--%Y年%m月%d",date:"$orderDate"}}]}}})

结果如下:

{

"_id" : ObjectId("59f841f5b998d8acc7d08861"),

"addr" : "NanJing--2017年10月31"

}

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

db.sang_collect.aggregate({$project:{addr:{$toLower:"$orderAddressL"}}})

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

db.sang_collect.aggregate({$project:{addr:{$toUpper:"$orderAddressL"}}})

逻辑表达式

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

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

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

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

至于我们之前介绍的ne/gte/lte等操作符在这里一样是适用的。另外还有or、and为例,如下:

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

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

db.sang_collect.aggregate({$project:{test:{$not:{"$eq":["$freight","$prodMoney"]}}}})

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

db.sang_collect.aggregate({$project:{test:{$cond:[false,"trueExpr","falseExpr"]}}})

$cond第一个参数如果为true,则返回trueExpr,否则返回falseExpr.

db.sang_collect.aggregate({$project:{test:{$ifNull:[null,"replacementExpr"]}}})

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

好了,MongoDB中的管道操作符我们就先说到这里,下篇文章继续,小伙伴们有问题欢迎留言讨论。

参考资料:

1.《MongoDB权威指南第2版》

2.mongodb聚合利用日期分组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值