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写法了。