Java + MongoDB : Group by name and count values of two different columns based on certain criteria

Java + MongoDB : Group by name and count values of two different columns based on certain criteria

我正在尝试在 Java 平台上获得想要的结果。 首先,MongoDB 的聚合框架对我来说很新。所以如果这个问题看起来微不足道,请原谅。但是我试图搜索类似的东西但无济于事。

原来的文档结构是这样的:

{
  "name" : "WS1",
  "previousCount" : 80,
  "currentCount" : 70
},
    {
  "name" : "WS2",
  "previousCount" : 42,
  "currentCount" : 10
},
    {
  "name" : "WS2",
  "previousCount" : 60,
  "currentCount" : 40
},
    {
  "name" : "WS1",
  "previousCount" : 60,
  "currentCount" : 20
},
    {
  "name" : "WS3",
  "previousCount" : 50,
  "currentCount" : 10
},
    {
  "name" : "WS3",
  "previousCount" : 30,
  "currentCount" : 70
},
    {
  "name" : "WS1",
  "previousCount" : 30,
  "currentCount" : 30
},
    {
  "name" : "WS1",
  "previousCount" : 80,
  "currentCount" : 50
},

我必须先根据名称对文档进行分组,然后对 previousCount 和 currentCount 字段应用过滤器并计算满足条件的出现次数。

所以如果我想要不同的记录来表示 previousCount 的次数 >=40<=70 和 currentCount是 >=10<=50,我应该得到这样的结果:

因此我最终想要这样的结果:

{
  "name" : "WS1",
  "qualifiedPreviousCount" : 2,
  "qualifiedCurrentCount" : 3
},
    {
  "name" : "WS2",
  "qualifiedPreviousCount" : 2,
  "qualifiedCurrentCount" : 2
},
    {
  "name" : "WS3",
  "qualifiedPreviousCount" : 1,
  "qualifiedCurrentCount" : 1
},

我该如何进行? MongoDB 的聚合框架是我发现很难理解和应用的东西。帮助将不胜感激,因为我被困在这里很长时间了。非常感谢。

您可以尝试以下聚合。

$group by name and $sum with $cond with conditions, when match set 1 else set 0.

db.collection_name.aggregate({
  "$group": {
    "_id": "$name",
    "qualifiedPreviousCount": {
      "$sum": {
        "$cond": [
          {
            "$and": [
              {
                "$gte": [
                  "$previousCount",
                  40
                ]
              },
              {
                "$lte": [
                  "$previousCount",
                  70
                ]
              }
            ]
          },
          1,
          0
        ]
      }
    },
    "qualifiedCurrentCount": {
      "$sum": {
        "$cond": [
          {
            "$and": [
              {
                "$gte": [
                  "$currentCount",
                  10
                ]
              },
              {
                "$lte": [
                  "$currentCount",
                  50
                ]
              }
            ]
          },
          1,
          0
        ]
      }
    }
  }
})

Java代码:

MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("db");
MongoCollection<Document> collection = db.getCollection("collection");
Bson aggregates = Aggregates.group("$name",
                Arrays.asList(Accumulators.sum("qualifiedPreviousCount", new Document("$cond", Arrays.<Object>asList(new Document("$and", Arrays.<Object>asList(
                        new Document("$gte", Arrays.<Object>asList("$previousCount", 40)), new Document("$gte", Arrays.<Object>asList("$previousCount", 70))
                )), 1, 0))), Accumulators.sum("qualifiedCurrentCount", new Document("$cond", Arrays.<Object>asList(new Document("$and", Arrays.<Object>asList(
                        new Document("$gte", Arrays.<Object>asList("$currentCount", 10)), new Document("$gte", Arrays.<Object>asList("$currentCount", 50))
                )), 1, 0)))));

List<Document> results = collection.aggregate(Arrays.asList(aggregates)).into(new ArrayList<>());