我想使用java代码运行这个mongodb查询。
查询:
public class SomeTemplateSelector : DataTemplateSelector
{
public DataTemplate OthersTemplate { get; set; }
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return DefaultTemplate;
}
}
我尝试使用此代码,但它没有用
db.log.aggregate([
{ $match : {
"ts" : {
$gte: ISODate("2015-07-31T18:30:00.000Z"),
$lt: ISODate("2015-08-01T18:30:00.000Z")
},
"dup": {$exists:false}
}},
{ $project : {
'lts': {
'$add': ['$ts',5.5*3600*1000]
}
}},
{ $group : {
_id : {
day: { $dayOfMonth: "$lts" },
month: { $month: "$lts" },
year: { $year: "$lts" }
},
count: { $sum: 1 }
}}
])
答案 0 :(得分:2)
您的初始查询可能写得更好。大概你想要按照" day"同时也从UTC调整到当地的timzezone。在这种情况下,通常最好只使用日期数学而不是混合date aggregation operators,这也意味着这里不需要$project
,你可以直接去{ {3}}:
db.log.aggregate([
{ "$match": {
"ts": {
"$gte": ISODate("2015-07-31T18:30:00.000Z"),
"$lt": ISODate("2015-08-01T18:30:00.000Z")
},
"dup": { "$exists": false }
}},
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
{ "$subtract": [
{ "$add": [ "$ts", 5.5*1000*60*60 ] },
new Date(0)
]},
{ "$mod": [
{ "$subtract": [
{ "$add": [ "$ts", 5.5*1000*60*60 ] },
new Date(0)
]},
1000*60*60*24
]}
]},
new Date(0)
]
},
"count": { "$sum": 1 }
}}
])
请注意其中的其他Date(0)
语句。这是" epoch"就像你$group
数字值到日期时得到Date
类型一样,当你$add
得到整数值时。因此,通过添加" epoch"进行纠正使所有内容再次成为Date
类型。
因此"日期数学"在任何地方都被雇用,以及#34; round"到了"日":
(1000毫秒* 60秒* 60分钟* 24小时)
模$subtract
运算符计算出从当前日期值中减去的剩余部分,来到"舍入"日期。
所有这些都在$group
完成并且也有效:
转换为Java只是遵循相同的缩进:
Date startdate = new DateTime(2015, 7, 31, 18, 30, 0, DateTimeZone.UTC).toDate();
Date enddate = new DateTime(2015, 8, 1, 18, 30, 0, DateTimeZone.UTC).toDate();
DBObject query = QueryBuilder.start()
.put("ts").greaterThanEquals(startdate)
.lessThan(enddate)
.and("dup").exists(false).get();
DBObject match = new BasicDBObject("$match",query);
DBObject group = new BasicDBObject("$group",
new BasicDBObject("_id",
new BasicDBObject(
"$add", Arrays.asList(
new BasicDBObject(
"$subtract", Arrays.asList(
new BasicDBObject(
"$subtract", Arrays.asList(
new BasicDBObject(
"$add",Arrays.asList( "$ts", 5.5*1000*60*60 )
),
new Date(0)
)
),
new BasicDBObject(
"$mod", Arrays.asList(
new BasicDBObject(
"$subtract", Arrays.asList(
new BasicDBObject(
"$add",Arrays.asList( "$ts", 5.5*1000*60*60 )
),
new Date(0)
)
),
1000*60*60*24
)
)
)
),
new Date(0)
)
)
)
.append("count", new BasicDBObject("$sum",1))
);
AggregationOutput output = collection.aggregate(Arrays.asList(match, group));
for ( DBObject result : output.results() ) {
System.out.println(result);
}
另请注意您的" timezeone调整"这里假设5.5小时"落后" UTC,我希望是正确的。如果你的意思是"""或者是肯定的,然后该操作是一个"减法"而不是将UTC时间更正为天的补充。
所以一切都很好,你的分组键也是真正的Date
个对象,而不是日期聚合运算符返回的复合值。
答案 1 :(得分:0)
将字段ts更改为东8时区:
import socket
import os
# Standard socket stuff:
host = ''
port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(5)
# Loop forever, listening for requests:
while True:
csock, caddr = sock.accept()
print("Connection from: " + str(caddr))
req = csock.recv(1024) # get the request, 1kB max
print(req)
# Look in the first line of the request for a move command
# A move command should be e.g. 'http://server/move?a=90'
filename = 'static/index.html'
f = open(filename, 'r')
csock.sendall(str.encode("HTTP/1.0 200 OK\n",'iso-8859-1'))
csock.sendall(str.encode('Content-Type: text/html\n', 'iso-8859-1'))
csock.send(str.encode('\r\n'))
# send data per line
for l in f.readlines():
print('Sent ', repr(l))
csock.sendall(str.encode(""+l+"", 'iso-8859-1'))
l = f.read(1024)
f.close()
csock.close()