java - Mongodb聚合命令转java代码

标签 java mongodb mongodb-query aggregation-framework

将 shell 命令转换为 Java 代码,

嗨,我想做的是,按“sourceSystemName”进行 GROUP 集合,并获取 logID、type、_id、sourceSystemName、logTime 的值以获取 MAX“logTime”

采集样本数据:(包含100万条数据)

{ "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" }

任务:

GROUP by "sourceSystemName"

get values of  logID,type,_id,sourceSystemName,logTime for MAX "logTime"

预期输出:

{ "_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") } ] }

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]
          ]
      }
  }
 }])

现在我需要将此命令转换为java代码,问题是,我不知道如何将$setDifference对象附加到DOCUMENT()对象mongodb java驱动程序。任何人都可以帮忙吗,

如果此输出有任何其他更好的解决方案,请建议我。

最佳答案

您可以尝试如下所示的操作。

    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<>());

或者

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<>());

或者更好的是使用$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<>());

关于java - Mongodb聚合命令转java代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42351139/

相关文章:

java - 如何在 Java 中正确建模战舰游戏

Java - 使用流 + lambdas 的多个集合的交集

mongodb - 按集合中 bool 值的计数分组

javascript - MongoDB with Mongoose - 选择指定日期范围丢弃时间

mongodb - 从 MongoDB 中获取产品属性的计数

javascript - 从用户时间轴获取转发计数

java - 从命令行错误在 Linux 上编译 Java 应用程序

java - 在 Java 中转换泛型类型

reactjs - 在 .env 中隐藏我的 MongoURI 变量会破坏我在 Heroku 上的应用程序

javascript - 将键值对象转换为仅值数组