Java + MongoDB:根据特定条件按名称和两个不同列的计数值进行分组

时间:2017-10-12 17:10:26

标签: java mongodb mongodb-query aggregation-framework mongodb-java

我想在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的聚合框架是我难以理解和应用的东西。我将非常感激帮助,因为我被困在这里很长时间。非常感谢提前。

1 个答案:

答案 0 :(得分:0)

您可以尝试以下聚合。

$group name$sum $cond 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 ] } } } }) 条件,匹配时设置1,否则设置为0。

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

Java代码:

general