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<>());
我正在尝试在 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<>());