问题
Convert shell command to Java code,
Hi what iam trying to do is, GROUP collection by "sourceSystemName" and get values of logID,type,_id,sourceSystemName,logTime for MAX "logTime"
Collection Sample Data:(contains 1million data)
{ "logID" : "1487408645950", "logTime" : ISODate("2017-02-6T06:47:59Z"), "type" : "SYSTEM_MONITOR", "sourceSystemId" :"192.168.1.226", "sourceSystemName" : "LOADER.LOG" }
{ "logID" : "1488226732268", "logTime" : ISODate("2017-02-16T06:48:00Z"),"type" : "SYSTEM_MONITOR", "sourceSystemId" :"192.168.1.226", "sourceSystemName" : "PLATFORM.LOG" }
{ "logID" : "1488293048361", "logTime" : ISODate("2017-02-16T06:48:01Z"),"type" : "SYSTEM_MONITOR", "sourceSystemId" :"192.168.1.226", "sourceSystemName" : "PLATFORM.LOG" }
{ "logID" : "1487496165381", "logTime" : ISODate("2017-02-16T06:48:03Z"),"type" : "SYSTEM_MONITOR", "sourceSystemId" :"192.168.1.226", "sourceSystemName" : "LOADER.LOG" }
Task:
GROUP by "sourceSystemName"
get values of logID,type,_id,sourceSystemName,logTime for MAX "logTime"
ExpectedOutput:
{ "_id" : "LOADER.LOG", "logTime" : ISODate("2017-02-16T20:44:06Z"), "result" : [ { "sourceSystemName" : "LOADER.LOG", "_id" : ObjectId("58a686bb1a20043138d47ecb"), "logID" : "1488673221443", "type" : "SYSTEM_MONITOR", "logTime" : ISODate("2017-02-16T20:44:06Z") } ] }
{ "_id" : "PLATFORM.LOG", "logTime" : ISODate("2017-02-16T08:42:25Z"), "result" : [ { "sourceSystemName" : "PLATFORM.LOG", "_id" : ObjectId("58a565f61a20041b81aa4017"), "logID" : "1487834117661", "type" : "SYSTEM_MONITOR", "logTime" : ISODate("2017-02-16T08:42:25Z") } ] }
Command used in MongoShell:
db.log_system_monitoring.aggregate([{
"$group": {
"_id": "$sourceSystemName",
"logTime": {
"$max": "$logTime"
},
"result": {
"$push": {
"_id": "$_id",
"logID": "$logID",
"type": "$type",
"logTime": "$logTime"
}
}
}
}, {
"$project": {
"logTime": 1,
"result": {
"$setDifference": [{
"$map": {
"input": "$result",
"as": "result",
"in": {
"$cond": [{
"$eq": ["$logTime", "$$result.logTime"]
},
"$$result",
false
]
}
}
},
[false]
]
}
}
}])
now i need to convert this command to java code, the problem is , i dont know how to append $setDifference object to DOCUMENT() object mongodb java driver. can anyone help this,
if there is anyother better solution for this output pls suggest me.
回答1:
You can try something like below.
List<Document> results =
collection.aggregate(
Arrays.asList(
Aggregates.group(
"$sourceSystemName",
max("logTime", "$logTime"),
push("result",
new Document("_id", "$id").
append("logID", "$logID").
append("type", "$type").
append("logTime", "$logTime"))
),
Aggregates.project(
fields(include("logTime"),
new Document("result",
new Document("$setDifference",
Arrays.asList(
new Document("$map",
new Document("input", "$result").
append("as", "result").
append("in",
new Document("$cond",
Arrays.asList(new Document("$eq", Arrays.asList("$logTime", "$$result.logTime")),
"$$result",
false)
)
)
),
Arrays.asList(false)
)
)
)
)
)
)
).into(new ArrayList<>());
OR
String maxResult = "{\n" +
"\t\"$setDifference\": [{\n" +
"\t\t\t\"$map\": {\n" +
"\t\t\t\t\"input\": \"$result\",\n" +
"\t\t\t\t\"as\": \"result\",\n" +
"\t\t\t\t\"in\": {\n" +
"\t\t\t\t\t\"$cond\": [{\n" +
"\t\t\t\t\t\t\t\"$eq\": [\"$logTime\", \"$$result.logTime\"]\n" +
"\t\t\t\t\t\t},\n" +
"\t\t\t\t\t\t\"$$result\",\n" +
"\t\t\t\t\t\tfalse\n" +
"\t\t\t\t\t]\n" +
"\t\t\t\t}\n" +
"\t\t\t}\n" +
"\t\t},\n" +
"\t\t[false]\n" +
"\t]\n" +
"}";
List<Document> results = collection.aggregate(Arrays.asList(Aggregates.group("$sourceSystemName", max("logTime", "$logTime"), push("result", new Document("_id", "$id").
append("logID", "$logID").
append("type", "$type").
append("logTime", "$logTime") )), Aggregates.project(fields(include("logTime"), new Document("result", Document.parse(maxResult)))
))).into(new ArrayList<>());
OR better would be to use $filter
String letFilter = "{\n" +
"\t$let: {\n" +
"\t\tvars: {\n" +
"\t\t\tlogTimeMax: {\n" +
"\t\t\t\t$max: \"$result.logTime\"\n" +
"\t\t\t}\n" +
"\t\t},\n" +
"\t\tin: {\n" +
"\t\t\t$filter: {\n" +
"\t\t\t\tinput: \"$result\",\n" +
"\t\t\t\tas: \"result\",\n" +
"\t\t\t\tcond: {\n" +
"\t\t\t\t\t$eq: [\"$$result.logTime\", '$$logTimeMax']\n" +
"\t\t\t\t}\n" +
"\t\t\t}\n" +
"\t\t}\n" +
"\t}\n" +
"}";
List<Document> results = collection.aggregate(Arrays.asList(Aggregates.group("$sourceSystemName", push("result", new Document("_id", "$id").
append("logID", "$logID").
append("type", "$type").
append("logTime", "$logTime") )), Aggregates.project(new Document("result", Document.parse(letFilter)))
)).into(new ArrayList<>());
来源:https://stackoverflow.com/questions/42351139/mongodb-aggregation-command-to-java-code