Search code examples
javamongodbaggregation-frameworkmongodb-java

Turn aggregation including $cond into DBObject in java


I have build an aggregation in MongoDB

{
    "$project": {
        "dt": "$dt",
        "mc": "$mc",
        "uplift": "$uplift",
        "baseAvg": "$baseAvg",
        "baseUp":  { $add: [ "$uplift", "$baseAvg" ] },
        "share": {
            "$cond": [{
                "$eq": ["$baseAvg", 0]
            }, 0, {
                "$divide": ["$uplift", "$baseAvg"]
            }]
        }
    } 
}

I'm trying to build the query by using DBObject since there is no ProjectOperation that supports condition. But I get stuck.

When I write this:

ArrayList condArray = new ArrayList();
        condArray.add(new BasicDBObject("$eq", new DBObject[] { new BasicDBObject("$baseAvg", 0) }));
        condArray.add(0);
        condArray.add(new BasicDBObject("$divide", new DBObject[] { new BasicDBObject("$uplift", "$baseAvg") }));

        DBObject doc = new BasicDBObject("$baseAvg", 0);


        DBObject operation = new BasicDBObject("$project",
                new BasicDBObject(groupItem, "$_id." + groupItem)   
                .append("mc", "$mc")
                .append("uplift", "$uplift")
                .append("baseAvg", "$baseAvg")
                .append("sumBaseUp", new BasicDBObject("$add", new DBObject[] {"$uplift", "$baseAvg"}))
                .append("share", new BasicDBObject("$cond", condArray)));

I get this as a result:

{
    "$project": {
        "dt": "$dt",
        "mc": "$mc",
        "uplift": "$uplift",
        "baseAvg": "$baseAvg",
        "sumBaseUp": {
            "$add": [{
                "$uplift": "$baseAvg"
            }]
        },
        "share": {
            "$cond": [{
                "$eq": [{
                    "$baseAvg": 0
                }]
            }, 0, {
                "$divide": [{
                    "$uplift": "$baseAvg"
                }]
            }]
        }
    }
}

Anybody knows what I should do?


Solution

  • You can use the below aggregation query for Mongo Java 2.13 version. I've simplified some operations.

     List<DBObject> aggregates = Arrays.asList(new BasicDBObject("$project", new BasicDBObject("dt", "$dt").
                append("mc", "$mc").
                append("uplift", "$uplift").
                append("baseAvg", "$baseAvg").
                append("baseUp", new BasicDBObject("$add", Arrays.<Object>asList("$uplift", "$baseAvg"))).
                append("share", new BasicDBObject("$cond", Arrays.<Object>asList(new BasicDBObject("$eq", Arrays.<Object>asList("$baseAvg", 0)),
                        0, new BasicDBObject("$divide",  Arrays.<Object>asList("$uplift", "$baseAvg")))))));
    

    For 3.x version you can use below aggregation.

     MongoClient mongoClient = new MongoClient();
     MongoDatabase db = mongoClient.getDatabase("db");
     MongoCollection<Document> collection = db.getCollection("collection");
     Bson aggregates = Aggregates.project(Projections.fields(Projections.include("dt", "mc", "uplift","baseAvg"),
                   new Document("baseUp", new Document("$add", Arrays.<Object>asList("$uplift", "$baseAvg"))),
                   new Document("share", new Document("$cond", Arrays.<Object>asList(new Document("$eq", Arrays.<Object>asList("$baseAvg", 0)),
                                            0, new Document("$divide",  Arrays.<Object>asList("$uplift", "$baseAvg")))))));
     List<Document> results = collection.aggregate(Arrays.asList(aggregates)).into(new ArrayList<>());