Mongodb Aggregation command to java code

走远了吗. 提交于 2019-12-25 18:35:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!