Mongo Java操作:按时间Group By

Mongo的Java API对于初学者来说真心不好用,基本操作还好,对于一些复杂的点的语法,很容易让人懵圈。

官网JAVA API的使用示例:

http://mongodb.github.io/mongo-java-driver/3.5/driver/tutorials/

https://docs.mongodb.com/manual/reference/sql-aggregation-comparison/   (sql和mongo sql 聚合写法对比)

 

跟时间操作相关的函数:

$dayOfYear: 返回该日期是这一年的第几天。(全年366天)
$dayOfMonth: 返回该日期是这一个月的第几天。(1到31)
$dayOfWeek: 返回的是这个周的星期几。(1:星期日,7:星期六)
$year: 返回该日期的年份部分
$month: 返回该日期的月份部分(between 1 and 12.)
$week: 返回该日期是所在年的第几个星期(between 0 and 53)
$hour: 返回该日期的小时部分
$minute: 返回该日期的分钟部分
$second: 返回该日期的秒部分(以0到59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒。)
$millisecond:返回该日期的毫秒部分(between 0 and 999.)
$dateToString:
    { $dateToString: { format: <formatString>, date: <dateExpression> } }

假设有如下的mongo集合:

> db.newAreaDayInfo.findOne()
{
        "_id" : ObjectId("57e9638844f50a0da4c0c128"),
        "id1" : "10001",
        "id2" : "20001",
        "areaInfo" : "广东",
        "activeDate" : ISODate("2016-09-25T16:00:00Z"),
        "daycnt" : NumberLong(2)
}

聚合查询:

db.newAreaDayInfo.aggregate(
   [
     {
       $project: {
          month: { $month: "$activeDate" }, 
          day: { $dayOfMonth: "$activeDate" }, 
          year: { $year: "$activeDate" }
          yearMonthDay: { $dateToString: { format: "%Y-%m-%d", date: "$activeDate" } },
          time: { $dateToString: { format: "%H:%M:%S:%L", date: "$activeDate" } }
       }
     }
   ]
)

查询结果:

{ 
"_id" : 1111,
"year" : 2016,
"month" : 09,
"day" : 25, 
"yearMonthDay" : "2016-09-25", 
"time" : "16:00:00:000" 
}

聚合查询:

db.newAreaDayInfo.aggregate(
   [
      {
        $group : {
           
           _id : { month: { $month: "$activeDate" }, 
                  day: { $dayOfMonth: "$activeDate" }, 
                  year: { $year: "$activeDate" } 
                 },
           totalActiveCount: { $sum: "$daycnt" },
           totalActiveCount2: { $sum: 1 }
        }
      }
   ]
)

 

重点来了, 对应的java写法:

        Document groupFields  = new Document("month", new Document("$month","$activeDate")).append("year", new Document("$year","$activeDate"))
        .append("day", new Document("$dayOfMonth","$activeDate"));        
        
        AggregateIterable<Document> iterable =
            collection
                .aggregate(
                    Arrays.asList(
Aggregates.group(groupFields,Accumulators.sum("totalActiveCount","$activeCount"),Accumulators.sum("totalActiveCount2", 1)),
Aggregates.sort(Sorts.ascending("_id.year", "_id.month"))
))
                .allowDiskUse(true);
        
        MongoCursor<Document> cursor = null;
        Map<String, Long> newActiveDeviceMap = new HashMap<String, Long>();
        
        try {
            cursor = iterable.iterator();
            Integer totalActiveCount = 0;
            Integer totalActiveCount2 = 0;
            Document resultDoc = null;
            Document groupObject = null;
            while (cursor.hasNext()) {
                resultDoc = cursor.next();
                groupObject = ((Document) resultDoc.get("_id"));
                System.out.println(groupObject);
                totalActiveCount = MapUtils.getInteger(resultDoc, "totalActiveCount", 0);
                totalActiveCount2 = MapUtils.getInteger(resultDoc, "totalActiveCount2", 0);
                System.out.println("totalActiveCount: " + totalActiveCount);
                System.out.println("totalActiveCount2: " + totalActiveCount2);
            }
        }
        finally {
            if (cursor != null) {
                cursor.close();
            }
        }

 

输出结果示例:

Document{{month=09, year=2016, day=25}}
totalActiveCount: 2
totalActiveCount2: 1

 

Mongo转化成JAVA写法心得:

用new Document(key, value)的形式来对应mongo 命令行查询语句。  Document类就可以看作是一个Map,因为他实现了Map类。

举例:

   _id : {        month: { $month: "$activeDate" }, 
                  day: { $dayOfMonth: "$activeDate" }, 
                  year: { $year: "$activeDate" } 
           },

对应成java写法:

Document groupFields  = 
new Document("month", new Document("$month","$activeDate"))
.append("year", new Document("$year","$activeDate"))
.append("day", new Document("$dayOfMonth","$activeDate")); 

  把month, day, year理解成key,

{ $month: "$activeDate" }, { $dayOfMonth: "$activeDate" },{ $year: "$activeDate" } 理解成对应map的value。

然后$month, $dayOfMonth, $year又理解成子map的key,相应的 "$activeDate"为对应子map的value。最后就可以很好的理解上面的java写法了。

 

 

转载于:https://my.oschina.net/trydaydayup/blog/1545321

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值